Compare commits

..
19 Commits
Author SHA1 Message Date
Kotmatross 1282056fff Fix blend leak in BatchingFontRenderer (#1575) 2026-03-25 15:34:43 -07:00
Alexdoru 6c422d47a2 Make the mod no-op on server (#1574) 2026-03-25 12:59:23 -07:00
DarkShadow44 057ea8035c Distant Horizons shader support (#1553) 2026-03-25 10:48:14 -07:00
Jason Mitchell 3ea47c8385 Various fixes (#1571) 2026-03-24 22:17:40 -07:00
Eclipse-Sol 306d732d81 Fixes 3rd person enchant glints z-fighting with the item model (#1569) 2026-03-24 17:24:23 -07:00
Jason Mitchell a483669579 Maybe fix botania mana pool rendering 2026-03-23 21:09:33 -07:00
Eclipse-SolandJason Mitchell 53996500d7 Fix modded enchant glints not being animated (#1566)
Co-authored-by: Jason Mitchell <[email protected]>
2026-03-23 22:41:29 -04:00
Jason Mitchell 04dd8ce6c7 narrow scope of mixin per Eclipse 2026-03-23 19:24:16 -07:00
Jason Mitchell 8c9edfa4c3 Fix alpha test 2026-03-23 19:24:16 -07:00
Jason Mitchell 3f44195756 Change compat config 2026-03-23 09:27:56 -07:00
Jason Mitchell c98f056d74 ASM Hook Compat
* Adds a config to allow disabling
* Narrows Advanced LightSabers
* Narrows Alfheim (unreleased versions have compat, might make this version restricted)
2026-03-23 09:00:24 -07:00
Jason Mitchell 7e25f5d03e tweak wording 2026-03-22 18:41:58 -07:00
Jason Mitchell b5553654d0 More pass throughs 2026-03-22 18:41:58 -07:00
Jason Mitchell a3fffb47be Ban GL usage.
* Everything must go through GLSM/Render Backend
2026-03-22 11:56:08 -07:00
Jason Mitchell 09cc557be0 Clear cache on reload shaders 2026-03-22 11:07:37 -07:00
SpacEagle17 aff5ff7e7b Add a second profiles button to Angelica 2026-03-22 10:09:23 -07:00
Jason Mitchell e7d08a53b6 Add debug context 2026-03-22 10:08:49 -07:00
Jason Mitchell 3b2a0af5c4 Add missing overrides 2026-03-22 10:08:49 -07:00
Jason Mitchell 8c44e79990 Add always translucent config for brandyn 2026-03-22 10:08:49 -07:00
116 changed files with 3253 additions and 1245 deletions

No files matched your search

+6 -1
View File
@@ -119,7 +119,7 @@ dependencies {
compileOnly("com.github.GTNewHorizons:NotEnoughIds:2.1.10:dev")
compileOnly(rfg.deobf("maven.modrinth:ntmspace:X5593_H261"))
compileOnly(rfg.deobf("maven.modrinth:ntmspace:X5634_H261"))
compileOnly(rfg.deobf("curse.maven:campfirebackport-387444:4611675"))
compileOnly(rfg.deobf("curse.maven:xaeros-minimap-263420:5060684"))
@@ -136,6 +136,9 @@ dependencies {
// Better Crashes
compileOnly("com.github.GTNewHorizons:BetterCrashes:1.4.1-GTNH:dev")
// Distant Horizons
compileOnly("maven.modrinth:DistantHorizonsApi:5.1.0")
afterEvaluate {
dependencies {
testImplementation(platform('org.junit:junit-bom:5.14.1'))
@@ -146,6 +149,8 @@ dependencies {
testImplementation('org.junit.platform:junit-platform-engine')
testImplementation('org.junit.platform:junit-platform-reporting')
testImplementation('org.junit.platform:junit-platform-launcher')
testImplementation('com.tngtech.archunit:archunit-junit5:1.4.1')
}
}
@@ -42,10 +42,11 @@ public class CompatUniformManager {
static final int LOC_IRIS_PROJECTION = 11;
static final int LOC_IRIS_NORMAL = 12;
static final int LOC_IRIS_LIGHTMAP_TEXTURE_MATRIX = 13;
static final int LOC_ALPHA_TEST_REF = 14;
static final int LOC_SCENE_COLOR = 15;
static final int LOC_CLIP_PLANES = 16;
static final int LOC_CLIP_PLANES_ENABLED = 17;
static final int LOC_IRIS_TEXTURE_MATRIX = 14;
static final int LOC_ALPHA_TEST_REF = 15;
static final int LOC_SCENE_COLOR = 16;
static final int LOC_CLIP_PLANES = 17;
static final int LOC_CLIP_PLANES_ENABLED = 18;
// Light source fields: 12 per light × 2 lights = 24 locations
static final int LIGHT_FIELDS = 12;
@@ -53,14 +54,14 @@ public class CompatUniformManager {
static final int LF_HALF_VECTOR = 4, LF_SPOT_DIRECTION = 5, LF_SPOT_EXPONENT = 6;
static final int LF_SPOT_CUTOFF = 7, LF_SPOT_COS_CUTOFF = 8;
static final int LF_CONSTANT_ATTEN = 9, LF_LINEAR_ATTEN = 10, LF_QUADRATIC_ATTEN = 11;
static final int LOC_LIGHT_BASE = 18;
static final int LOC_LIGHT_BASE = 19;
// Material fields: 5 locations
static final int MF_EMISSION = 0, MF_AMBIENT = 1, MF_DIFFUSE = 2, MF_SPECULAR = 3, MF_SHININESS = 4;
static final int MAT_FIELDS = 5;
static final int LOC_MAT_BASE = LOC_LIGHT_BASE + 2 * LIGHT_FIELDS; // 42
static final int LOC_MAT_BASE = LOC_LIGHT_BASE + 2 * LIGHT_FIELDS; // 43
static final int LOC_COUNT = LOC_MAT_BASE + MAT_FIELDS; // 47
static final int LOC_COUNT = LOC_MAT_BASE + MAT_FIELDS; // 48
private static final String[] LIGHT_FIELD_NAMES = {
"ambient", "diffuse", "specular", "position", "halfVector",
@@ -89,6 +90,7 @@ public class CompatUniformManager {
UNIFORM_NAMES[LOC_IRIS_PROJECTION] = "iris_ProjectionMatrix";
UNIFORM_NAMES[LOC_IRIS_NORMAL] = "iris_NormalMatrix";
UNIFORM_NAMES[LOC_IRIS_LIGHTMAP_TEXTURE_MATRIX] = "iris_LightmapTextureMatrix";
UNIFORM_NAMES[LOC_IRIS_TEXTURE_MATRIX] = "iris_TextureMatrix";
UNIFORM_NAMES[LOC_ALPHA_TEST_REF] = "angelica_currentAlphaTest";
UNIFORM_NAMES[LOC_SCENE_COLOR] = "angelica_SceneColor";
UNIFORM_NAMES[LOC_CLIP_PLANES] = "angelica_ClipPlane[0]";
@@ -264,6 +266,12 @@ public class CompatUniformManager {
GLStateManager.getTextures().getTextureUnitMatrix(1).get(mat4Buf);
RENDER_BACKEND.uniformMatrix4(locs[LOC_LIGHTMAP_TEXTURE_MATRIX], false, mat4Buf);
}
// iris_TextureMatrix — texture unit 0 matrix (animated by glints, etc.)
if (locs[LOC_IRIS_TEXTURE_MATRIX] != -1) {
GLStateManager.getTextures().getTextureUnitMatrix(0).get(mat4Buf);
RENDER_BACKEND.uniformMatrix4(locs[LOC_IRIS_TEXTURE_MATRIX], false, mat4Buf);
}
}
}
@@ -4901,13 +4901,23 @@ public class GLStateManager {
public static void glBufferData(int target, int[] data, int usage) { RENDER_BACKEND.bufferData(target, data, usage); }
public static void glBufferData(int target, float[] data, int usage) { RENDER_BACKEND.bufferData(target, data, usage); }
public static void glBufferData(int target, java.nio.ByteBuffer data, int usage) { RENDER_BACKEND.bufferData(target, data, usage); }
public static void glBufferData(int target, java.nio.FloatBuffer data, int usage) { RENDER_BACKEND.bufferData(target, data, usage); }
public static void glBufferData(int target, java.nio.ShortBuffer data, int usage) { RENDER_BACKEND.bufferData(target, data, usage); }
public static void glBufferData(int target, java.nio.IntBuffer data, int usage) { RENDER_BACKEND.bufferData(target, data, usage); }
public static void glBufferData(int target, java.nio.FloatBuffer data, int usage) { RENDER_BACKEND.bufferData(target, data, usage); }
public static void glBufferData(int target, java.nio.DoubleBuffer data, int usage) { RENDER_BACKEND.bufferData(target, data, usage); }
public static void glBufferSubData(int target, long offset, java.nio.ByteBuffer data) { RENDER_BACKEND.bufferSubData(target, offset, data); }
public static void glBufferSubData(int target, long offset, java.nio.ShortBuffer data) { RENDER_BACKEND.bufferSubData(target, offset, data); }
public static void glBufferSubData(int target, long offset, java.nio.IntBuffer data) { RENDER_BACKEND.bufferSubData(target, offset, data); }
public static void glBufferSubData(int target, long offset, java.nio.FloatBuffer data) { RENDER_BACKEND.bufferSubData(target, offset, data); }
public static void glBufferSubData(int target, long offset, java.nio.DoubleBuffer data) { RENDER_BACKEND.bufferSubData(target, offset, data); }
public static ByteBuffer glMapBuffer(int target, int access) { return RENDER_BACKEND.mapBuffer(target, access); }
public static ByteBuffer glMapBuffer(int target, int access, long length, ByteBuffer old_buffer) { return RENDER_BACKEND.mapBuffer(target, access, length, old_buffer); }
public static boolean glUnmapBuffer(int target) { return RENDER_BACKEND.unmapBuffer(target); }
public static void glGetBufferSubData(int target, long offset, java.nio.ByteBuffer data) { RENDER_BACKEND.getBufferSubData(target, offset, data); }
public static void glGetBufferSubData(int target, long offset, java.nio.ShortBuffer data) { RENDER_BACKEND.getBufferSubData(target, offset, data); }
public static void glGetBufferSubData(int target, long offset, java.nio.IntBuffer data) { RENDER_BACKEND.getBufferSubData(target, offset, data); }
public static void glGetBufferSubData(int target, long offset, java.nio.FloatBuffer data) { RENDER_BACKEND.getBufferSubData(target, offset, data); }
public static void glGetBufferSubData(int target, long offset, java.nio.DoubleBuffer data) { RENDER_BACKEND.getBufferSubData(target, offset, data); }
public static int glGetBufferParameteri(int target, int pname) { return RENDER_BACKEND.getBufferParameteri(target, pname); }
public static void glBufferStorage(int target, java.nio.ByteBuffer data, int flags) { RENDER_BACKEND.bufferStorage(target, data, flags); }
public static void glBufferStorage(int target, long size, int flags) { RENDER_BACKEND.bufferStorage(target, size, flags); }
@@ -5023,6 +5033,14 @@ public class GLStateManager {
public static void glFramebufferTexture(int target, int attachment, int texture, int level) { RENDER_BACKEND.framebufferTexture(target, attachment, texture, level); }
public static void glGenerateMipmap(int target) {
RENDER_BACKEND.generateMipmap(target);
}
public static void glBlitFramebuffer(int srcX0, int srcY0, int srcX1, int srcY1, int dstX0, int dstY0, int dstX1, int dstY1, int mask, int filter) {
RENDER_BACKEND.blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
}
public static void setActiveTexture(int textureUnit) {
glActiveTexture(textureUnit);
}
@@ -902,6 +902,16 @@ public final class Lwjgl2GLRenderBackend extends RenderBackend {
GL15.glBufferData(target, data, usage);
}
@Override
public void bufferData(int target, IntBuffer data, int usage) {
GL15.glBufferData(target, data, usage);
}
@Override
public void bufferData(int target, DoubleBuffer data, int usage) {
GL15.glBufferData(target, data, usage);
}
@Override
public void bufferData(int target, int[] data, int usage) {
final IntBuffer buffer = getIntArrayBuffer(data.length);
@@ -923,6 +933,26 @@ public final class Lwjgl2GLRenderBackend extends RenderBackend {
GL15.glBufferSubData(target, offset, data);
}
@Override
public void bufferSubData(int target, long offset, ShortBuffer data) {
GL15.glBufferSubData(target, offset, data);
}
@Override
public void bufferSubData(int target, long offset, IntBuffer data) {
GL15.glBufferSubData(target, offset, data);
}
@Override
public void bufferSubData(int target, long offset, FloatBuffer data) {
GL15.glBufferSubData(target, offset, data);
}
@Override
public void bufferSubData(int target, long offset, DoubleBuffer data) {
GL15.glBufferSubData(target, offset, data);
}
@Override
public ByteBuffer mapBuffer(int target, int access) {
return GL15.glMapBuffer(target, access, null);
@@ -953,6 +983,26 @@ public final class Lwjgl2GLRenderBackend extends RenderBackend {
GL15.glGetBufferSubData(target, offset, data);
}
@Override
public void getBufferSubData(int target, long offset, ShortBuffer data) {
GL15.glGetBufferSubData(target, offset, data);
}
@Override
public void getBufferSubData(int target, long offset, IntBuffer data) {
GL15.glGetBufferSubData(target, offset, data);
}
@Override
public void getBufferSubData(int target, long offset, FloatBuffer data) {
GL15.glGetBufferSubData(target, offset, data);
}
@Override
public void getBufferSubData(int target, long offset, DoubleBuffer data) {
GL15.glGetBufferSubData(target, offset, data);
}
@Override
public int getBufferParameteri(int target, int pname) {
return GL15.glGetBufferParameteri(target, pname);
@@ -208,15 +208,25 @@ public abstract class RenderBackend {
public abstract void bufferData(int target, ByteBuffer data, int usage);
public abstract void bufferData(int target, FloatBuffer data, int usage);
public abstract void bufferData(int target, ShortBuffer data, int usage);
public abstract void bufferData(int target, IntBuffer data, int usage);
public abstract void bufferData(int target, DoubleBuffer data, int usage);
public abstract void bufferData(int target, int[] data, int usage);
public abstract void bufferData(int target, float[] data, int usage);
public abstract void bufferSubData(int target, long offset, ByteBuffer data);
public abstract void bufferSubData(int target, long offset, ShortBuffer data);
public abstract void bufferSubData(int target, long offset, IntBuffer data);
public abstract void bufferSubData(int target, long offset, FloatBuffer data);
public abstract void bufferSubData(int target, long offset, DoubleBuffer data);
public abstract ByteBuffer mapBuffer(int target, int access);
public abstract ByteBuffer mapBuffer(int target, int access, long length, ByteBuffer old_buffer);
public abstract boolean unmapBuffer(int target);
public abstract void bufferStorage(int target, ByteBuffer data, int flags);
public abstract void bufferStorage(int target, long size, int flags);
public abstract void getBufferSubData(int target, long offset, ByteBuffer data);
public abstract void getBufferSubData(int target, long offset, ShortBuffer data);
public abstract void getBufferSubData(int target, long offset, IntBuffer data);
public abstract void getBufferSubData(int target, long offset, FloatBuffer data);
public abstract void getBufferSubData(int target, long offset, DoubleBuffer data);
public abstract int getBufferParameteri(int target, int pname);
public abstract boolean isBuffer(int buffer);
public abstract ByteBuffer mapBufferRange(int target, long offset, long length, int access);
@@ -893,6 +893,16 @@ public final class Lwjgl3GLRenderBackend extends RenderBackend {
GL15C.glBufferData(target, data, usage);
}
@Override
public void bufferData(int target, IntBuffer data, int usage) {
GL15C.glBufferData(target, data, usage);
}
@Override
public void bufferData(int target, DoubleBuffer data, int usage) {
GL15C.glBufferData(target, data, usage);
}
@Override
public void bufferData(int target, int[] data, int usage) {
GL15C.glBufferData(target, data, usage);
@@ -908,6 +918,26 @@ public final class Lwjgl3GLRenderBackend extends RenderBackend {
GL15C.glBufferSubData(target, offset, data);
}
@Override
public void bufferSubData(int target, long offset, ShortBuffer data) {
GL15C.glBufferSubData(target, offset, data);
}
@Override
public void bufferSubData(int target, long offset, IntBuffer data) {
GL15C.glBufferSubData(target, offset, data);
}
@Override
public void bufferSubData(int target, long offset, FloatBuffer data) {
GL15C.glBufferSubData(target, offset, data);
}
@Override
public void bufferSubData(int target, long offset, DoubleBuffer data) {
GL15C.glBufferSubData(target, offset, data);
}
@Override
public ByteBuffer mapBuffer(int target, int access) {
return GL15C.glMapBuffer(target, access);
@@ -938,6 +968,26 @@ public final class Lwjgl3GLRenderBackend extends RenderBackend {
GL15C.glGetBufferSubData(target, offset, data);
}
@Override
public void getBufferSubData(int target, long offset, ShortBuffer data) {
GL15C.glGetBufferSubData(target, offset, data);
}
@Override
public void getBufferSubData(int target, long offset, IntBuffer data) {
GL15C.glGetBufferSubData(target, offset, data);
}
@Override
public void getBufferSubData(int target, long offset, FloatBuffer data) {
GL15C.glGetBufferSubData(target, offset, data);
}
@Override
public void getBufferSubData(int target, long offset, DoubleBuffer data) {
GL15C.glGetBufferSubData(target, offset, data);
}
@Override
public int getBufferParameteri(int target, int pname) {
return GL15C.glGetBufferParameteri(target, pname);
@@ -1,17 +1,11 @@
package com.gtnewhorizons.angelica;
import com.gtnewhorizons.angelica.common.BlockError;
import com.gtnewhorizons.angelica.compat.ModStatus;
import com.gtnewhorizons.angelica.config.ConfigMigrator;
import com.gtnewhorizons.angelica.proxy.CommonProxy;
import com.gtnewhorizons.angelica.utils.AnimationMode;
import com.gtnewhorizons.angelica.utils.ManagedEnum;
import cpw.mods.fml.common.Mod;
import cpw.mods.fml.common.SidedProxy;
import cpw.mods.fml.common.event.FMLInitializationEvent;
import cpw.mods.fml.common.event.FMLPostInitializationEvent;
import cpw.mods.fml.common.event.FMLPreInitializationEvent;
import me.jellysquid.mods.sodium.client.gui.SodiumGameOptions;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@@ -32,32 +26,19 @@ import static com.gtnewhorizons.angelica.AngelicaMod.MOD_ID;
acceptableRemoteVersions = "*",
guiFactory = "com.gtnewhorizons.angelica.config.AngelicaGuiConfigFactory")
public class AngelicaMod {
public static final String MOD_ID = "angelica";
public static final Logger LOGGER = LogManager.getLogger("Angelica");
public static final boolean lwjglDebug = Boolean.getBoolean("org.lwjgl.util.Debug");
private static SodiumGameOptions CONFIG;
public static SodiumGameOptions options() {
if (CONFIG == null) {
CONFIG = SodiumGameOptions.load(ConfigMigrator.handleConfigMigration("angelica-options.json"));
}
return CONFIG;
}
@SidedProxy(clientSide = "com.gtnewhorizons.angelica.proxy.ClientProxy", serverSide = "com.gtnewhorizons.angelica.proxy.CommonProxy")
@SidedProxy(
clientSide = "com.gtnewhorizons.angelica.proxy.ClientProxy",
serverSide = "com.gtnewhorizons.angelica.proxy.CommonProxy")
public static CommonProxy proxy;
public static final boolean lwjglDebug = Boolean.parseBoolean(System.getProperty("org.lwjgl.util.Debug", "false"));
public static final ManagedEnum<AnimationMode> animationsMode = new ManagedEnum<>(AnimationMode.VISIBLE_ONLY);
public static BlockError blockError;
@Mod.EventHandler
public void preInit(FMLPreInitializationEvent event) {
ModStatus.preInit();
proxy.preInit(event);
blockError = new BlockError();
}
@Mod.EventHandler
@@ -1,707 +0,0 @@
package com.gtnewhorizons.angelica.client.debug;
import com.gtnewhorizons.angelica.glsm.GLDebug;
import com.gtnewhorizons.angelica.glsm.GLStateManager;
import com.gtnewhorizons.angelica.glsm.states.TextureUnitArray;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.texture.ITextureObject;
import net.minecraft.util.ResourceLocation;
import org.apache.commons.io.FileUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.joml.Matrix4f;
import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL12;
import org.lwjgl.opengl.GL13;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferInt;
import java.io.File;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.function.Consumer;
// Adapted from https://github.com/makamys/CoreTweaks/blob/master/src/main/java/makamys/coretweaks/util/OpenGLDebugging.java;
// originally from https://github.com/TheGreyGhost/MinecraftByExample/blob/1-8final/src/main/java/minecraftbyexample/usefultools/OpenGLdebugging.java
public class OpenGLDebugging {
public static final Logger LOGGER = LogManager.getLogger("gldumper");
private static final Consumer<String> LINE_LOGGER = LOGGER::debug;
private static final Set<String> seenErrors = new HashSet<>();
public static final String GL_IS_ENABLED = "glIsEnabled()";
public static final String GL_GET_BOOLEANV = "glGetBooleanv()";
public static final String GL_GET_INTEGERV = "glGetIntegerv()";
public static final String GL_GET_FLOATV = "glGetFloatv()";
public static class GLproperty {
public GLproperty(int glConstant, String name, String description, String category, String fetchCommand) {
this.gLConstant = glConstant;
this.name = name;
this.description = description;
this.category = category;
this.fetchCommand = fetchCommand;
}
public int gLConstant;
public String name;
public String description;
public String category;
public String fetchCommand;
static final ByteBuffer byteBuffer = BufferUtils.createByteBuffer(16);
static final IntBuffer intBuffer = BufferUtils.createIntBuffer(16);
static final FloatBuffer floatBuffer = BufferUtils.createFloatBuffer(16);
public String getAsString(boolean glsm) {
switch(fetchCommand) {
case GL_IS_ENABLED: {
return "" + (glsm ? GLStateManager.glIsEnabled(gLConstant) : GL11.glIsEnabled(gLConstant));
}
case GL_GET_BOOLEANV: {
if(GLStateManager.HAS_MULTIPLE_SET.contains(gLConstant)) {
byteBuffer.clear();
if(glsm) {
GLStateManager.glGetBoolean(gLConstant, byteBuffer);
} else {
GL11.glGetBoolean(gLConstant, byteBuffer);
}
final StringBuilder out = new StringBuilder();
for (int i = 0; i < byteBuffer.capacity(); ++i) {
out.append(i == 0 ? "" : ", ").append(byteBuffer.get(i));
}
return out.toString();
} else {
return "" + (glsm ? GLStateManager.glGetBoolean(gLConstant) : GL11.glGetBoolean(gLConstant));
}
}
case GL_GET_INTEGERV: {
if(GLStateManager.HAS_MULTIPLE_SET.contains(gLConstant)) {
intBuffer.clear();
if(glsm) {
GLStateManager.glGetInteger(gLConstant, intBuffer);
} else {
GL11.glGetInteger(gLConstant, intBuffer);
}
final StringBuilder out = new StringBuilder();
for (int i = 0; i < intBuffer.remaining(); ++i) {
out.append(i == 0 ? "" : ", ").append(intBuffer.get(i));
}
return out.toString();
} else {
return "" + (glsm ? GLStateManager.glGetInteger(gLConstant) : GL11.glGetInteger(gLConstant));
}
}
case GL_GET_FLOATV: {
if(GLStateManager.HAS_MULTIPLE_SET.contains(gLConstant)) {
floatBuffer.clear();
if(glsm) {
GLStateManager.glGetFloat(gLConstant, floatBuffer);
} else {
GL11.glGetFloat(gLConstant, floatBuffer);
}
final StringBuilder out = new StringBuilder();
for (int i = 0; i < floatBuffer.remaining(); ++i) {
out.append(i == 0 ? "" : ", ").append(String.format("%f", floatBuffer.get(i)));
}
return out.toString();
} else {
return "" + (glsm ? GLStateManager.glGetFloat(gLConstant) : GL11.glGetFloat(gLConstant));
}
}
default: return "";
}
}
static final Matrix4f cachedMatrix = new Matrix4f();
static final Matrix4f uncachedMatrix = new Matrix4f();
public Matrix4f getAsMatrix4f(boolean glsm) {
if(!fetchCommand.equals(GL_GET_FLOATV)) {
throw new IllegalArgumentException("This property does not return a matrix");
}
floatBuffer.clear();
if(glsm) {
GLStateManager.glGetFloat(gLConstant, floatBuffer);
return cachedMatrix.set(0, floatBuffer);
} else {
GL11.glGetFloat(gLConstant, floatBuffer);
return uncachedMatrix.set(0, floatBuffer);
}
}
}
public static OpenGLDebugging instance = new OpenGLDebugging();
public GLproperty[] propertyList = {
new GLproperty(GL11.GL_ACCUM_ALPHA_BITS, "GL_ACCUM_ALPHA_BITS", "Number of bits per alpha component in the accumulation buffer", "capability", GL_GET_INTEGERV),
new GLproperty(GL11.GL_ACCUM_BLUE_BITS, "GL_ACCUM_BLUE_BITS", "Number of bits per blue component in the accumulation buffer", "capability", GL_GET_INTEGERV),
new GLproperty(GL11.GL_ACCUM_CLEAR_VALUE, "GL_ACCUM_CLEAR_VALUE", "Accumulation-buffer clear value", "accum-buffer", GL_GET_FLOATV),
new GLproperty(GL11.GL_ACCUM_GREEN_BITS, "GL_ACCUM_GREEN_BITS", "Number of bits per green component in the accumulation buffer", "capability", GL_GET_INTEGERV),
new GLproperty(GL11.GL_ACCUM_RED_BITS, "GL_ACCUM_RED_BITS", "Number of bits per red component in the accumulation buffer", "capability", GL_GET_INTEGERV),
new GLproperty(GL11.GL_ALPHA_BITS, "GL_ALPHA_BITS", "Number of bits per alpha component in color buffers", "capability", GL_GET_INTEGERV),
new GLproperty(GL11.GL_ALPHA_TEST, "GL_ALPHA_TEST", "Alpha test enabled", "color-buffer/enable", GL_IS_ENABLED),
new GLproperty(GL11.GL_ALPHA_TEST_FUNC, "GL_ALPHA_TEST_FUNC", "Alpha test function", "color-buffer", GL_GET_INTEGERV),
new GLproperty(GL11.GL_ALPHA_TEST_REF, "GL_ALPHA_TEST_REF", "Alpha test reference value", "color-buffer", GL_GET_FLOATV),
new GLproperty(GL11.GL_AMBIENT, "GL_AMBIENT", "Ambient intensity of light i", "lighting", "glGetLightfv()"),
new GLproperty(GL11.GL_AMBIENT, "GL_AMBIENT", "Ambient material color", "lighting", "glGetMaterialfv()"),
new GLproperty(GL11.GL_ATTRIB_STACK_DEPTH, "GL_ATTRIB_STACK_DEPTH", "Attribute stack pointer", "current", GL_GET_INTEGERV),
new GLproperty(GL11.GL_AUTO_NORMAL, "GL_AUTO_NORMAL", "True if automatic normal generation enabled", "eval", GL_IS_ENABLED),
new GLproperty(GL11.GL_AUX_BUFFERS, "GL_AUX_BUFFERS", "Number of auxiliary buffers", "capability", GL_GET_BOOLEANV),
new GLproperty(GL11.GL_BLEND, "GL_BLEND", "Blending enabled", "color-buffer/enable", GL_IS_ENABLED),
new GLproperty(GL11.GL_BLEND_DST, "GL_BLEND_DST", "Blending destination function", "color-buffer", GL_GET_INTEGERV),
new GLproperty(GL11.GL_BLEND_SRC, "GL_BLEND_SRC", "Blending source function", "color-buffer", GL_GET_INTEGERV),
new GLproperty(GL11.GL_BLUE_BITS, "GL_BLUE_BITS", "Number of bits per blue component in color buffers", "capability", GL_GET_INTEGERV),
new GLproperty(GL11.GL_CLIENT_ATTRIB_STACK_DEPTH, "GL_CLIENT_ATTRIB_STACK_DEPTH", "Client attribute stack pointer", "current", GL_GET_INTEGERV),
new GLproperty(GL11.GL_COEFF, "GL_COEFF", "1D control points", "capability", "glGetMapfv()"),
new GLproperty(GL11.GL_COEFF, "GL_COEFF", "2D control points", "capability", "glGetMapfv()"),
new GLproperty(GL11.GL_COLOR_ARRAY, "GL_COLOR_ARRAY", "RGBA color array enable", "vertex-array", GL_IS_ENABLED),
new GLproperty(GL11.GL_COLOR_ARRAY_POINTER, "GL_COLOR_ARRAY_POINTER", "Pointer to the color array", "vertex-array", "glGetPointerv()"),
new GLproperty(GL11.GL_COLOR_ARRAY_SIZE, "GL_COLOR_ARRAY_SIZE", "Colors per vertex", "vertex-array", GL_GET_INTEGERV),
new GLproperty(GL11.GL_COLOR_ARRAY_STRIDE, "GL_COLOR_ARRAY_STRIDE", "Stride between colors", "vertex-array", GL_GET_INTEGERV),
new GLproperty(GL11.GL_COLOR_ARRAY_TYPE, "GL_COLOR_ARRAY_TYPE", "Type of color components", "vertex-array", GL_GET_INTEGERV),
new GLproperty(GL11.GL_COLOR_CLEAR_VALUE, "GL_COLOR_CLEAR_VALUE", "Color-buffer clear value (RGBA mode)", "color-buffer", GL_GET_FLOATV),
new GLproperty(GL11.GL_COLOR_INDEXES, "GL_COLOR_INDEXES", "ca, cd, and cs for color-index lighting", "lighting/e nable", "glGetMaterialfv()"),
new GLproperty(GL11.GL_COLOR_LOGIC_OP, "GL_COLOR_LOGIC_OP", "RGBA color logical operation enabled", "color-buffer/enable", GL_IS_ENABLED),
new GLproperty(GL11.GL_COLOR_MATERIAL, "GL_COLOR_MATERIAL", "True if color tracking is enabled", "lighting", GL_IS_ENABLED),
new GLproperty(GL11.GL_COLOR_MATERIAL_FACE, "GL_COLOR_MATERIAL_FACE", "Face(s) affected by color tracking", "lighting", GL_GET_INTEGERV),
new GLproperty(GL11.GL_COLOR_MATERIAL_PARAMETER, "GL_COLOR_MATERIAL_PARAMETER", "Material properties tracking current color", "lighting", GL_GET_INTEGERV),
new GLproperty(GL11.GL_COLOR_WRITEMASK, "GL_COLOR_WRITEMASK", "Color write enables; R, G, B, or A", "color-buffer", GL_GET_BOOLEANV),
new GLproperty(GL11.GL_CONSTANT_ATTENUATION, "GL_CONSTANT_ATTENUATION", "Constant attenuation factor", "lighting", "glGetLightfv()"),
new GLproperty(GL11.GL_CULL_FACE, "GL_CULL_FACE", "Polygon culling enabled", "polygon/enable", GL_IS_ENABLED),
new GLproperty(GL11.GL_CULL_FACE_MODE, "GL_CULL_FACE_MODE", "Cull front-/back-facing polygons", "polygon", GL_GET_INTEGERV),
new GLproperty(GL11.GL_CURRENT_COLOR, "GL_CURRENT_COLOR", "Current color", "current", GL_GET_FLOATV),
new GLproperty(GL11.GL_CURRENT_INDEX, "GL_CURRENT_INDEX", "Current color index", "current", GL_GET_FLOATV),
new GLproperty(GL11.GL_CURRENT_NORMAL, "GL_CURRENT_NORMAL", "Current normal", "current", GL_GET_FLOATV),
new GLproperty(GL11.GL_CURRENT_RASTER_COLOR, "GL_CURRENT_RASTER_COLOR", "Color associated with raster position", "current", GL_GET_FLOATV),
new GLproperty(GL11.GL_CURRENT_RASTER_DISTANCE, "GL_CURRENT_RASTER_DISTANCE", "Current raster distance", "current", GL_GET_FLOATV),
new GLproperty(GL11.GL_CURRENT_RASTER_INDEX, "GL_CURRENT_RASTER_INDEX", "Color index associated with raster position", "current", GL_GET_FLOATV),
new GLproperty(GL11.GL_CURRENT_RASTER_POSITION, "GL_CURRENT_RASTER_POSITION", "Current raster position", "current", GL_GET_FLOATV),
new GLproperty(GL11.GL_CURRENT_RASTER_POSITION_VALID, "GL_CURRENT_RASTER_POSITION_VALID", "Raster position valid bit", "current", GL_GET_BOOLEANV),
new GLproperty(GL11.GL_CURRENT_RASTER_TEXTURE_COORDS, "GL_CURRENT_RASTER_TEXTURE_COORDS", "Texture coordinates associated with raster position", "current", GL_GET_FLOATV),
new GLproperty(GL11.GL_CURRENT_TEXTURE_COORDS, "GL_CURRENT_TEXTURE_COORDS", "Current texture coordinates", "current", GL_GET_FLOATV),
new GLproperty(GL11.GL_DEPTH_BITS, "GL_DEPTH_BITS", "Number of depth-buffer bitplanes", "capability", GL_GET_INTEGERV),
new GLproperty(GL11.GL_DEPTH_CLEAR_VALUE, "GL_DEPTH_CLEAR_VALUE", "Depth-buffer clear value", "depth-buffer", GL_GET_INTEGERV),
new GLproperty(GL11.GL_DEPTH_FUNC, "GL_DEPTH_FUNC", "Depth buffer test function", "depth-buffer", GL_GET_INTEGERV),
new GLproperty(GL11.GL_DEPTH_RANGE, "GL_DEPTH_RANGE", "Depth range near and far", "viewport", GL_GET_FLOATV),
new GLproperty(GL11.GL_DEPTH_TEST, "GL_DEPTH_TEST", "Depth buffer enabled", "depth-buffer/ena ble", GL_IS_ENABLED),
new GLproperty(GL11.GL_DEPTH_WRITEMASK, "GL_DEPTH_WRITEMASK", "Depth buffer enabled for writing", "depth-buffer", GL_GET_BOOLEANV),
new GLproperty(GL11.GL_DIFFUSE, "GL_DIFFUSE", "Diffuse intensity of light i", "lighting", "glGetLightfv()"),
new GLproperty(GL11.GL_DIFFUSE, "GL_DIFFUSE", "Diffuse material color", "lighting", "glGetMaterialfv()"),
new GLproperty(GL11.GL_DITHER, "GL_DITHER", "Dithering enabled", "color-buffer/enable", GL_IS_ENABLED),
new GLproperty(GL11.GL_DOMAIN, "GL_DOMAIN", "1D domain endpoints", "capability", "glGetMapfv()"),
new GLproperty(GL11.GL_DOMAIN, "GL_DOMAIN", "2D domain endpoints", "capability", "glGetMapfv()"),
new GLproperty(GL11.GL_DOUBLEBUFFER, "GL_DOUBLEBUFFER", "True if front and back buffers exist", "capability", GL_GET_BOOLEANV),
new GLproperty(GL11.GL_DRAW_BUFFER, "GL_DRAW_BUFFER", "Buffers selected for drawing", "color-buffer", GL_GET_INTEGERV),
new GLproperty(GL11.GL_EDGE_FLAG, "GL_EDGE_FLAG", "Edge flag", "current", GL_GET_BOOLEANV),
new GLproperty(GL11.GL_EDGE_FLAG_ARRAY, "GL_EDGE_FLAG_ARRAY", "Edge flag array enable", "vertex-array", GL_IS_ENABLED),
new GLproperty(GL11.GL_EDGE_FLAG_ARRAY_POINTER, "GL_EDGE_FLAG_ARRAY_POINTER", "Pointer to the edge flag array", "vertex-array", "glGetPointerv()"),
new GLproperty(GL11.GL_EDGE_FLAG_ARRAY_STRIDE, "GL_EDGE_FLAG_ARRAY_STRIDE", "Stride between edge flags", "vertex-array", GL_GET_INTEGERV),
new GLproperty(GL11.GL_EMISSION, "GL_EMISSION", "Emissive material color", "lighting", "glGetMaterialfv()"),
new GLproperty(GL11.GL_EYE_PLANE, "GL_EYE_PLANE", "Texgen plane equation coefficients", "texture", "glGetTexGenfv()"),
new GLproperty(GL11.GL_FEEDBACK_BUFFER_POINTER, "GL_FEEDBACK_BUFFER_POINTER", "Pointer to feedback buffer", "feedback", "glGetPointerv()"),
new GLproperty(GL11.GL_FEEDBACK_BUFFER_SIZE, "GL_FEEDBACK_BUFFER_SIZE", "Size of feedback buffer", "feedback", GL_GET_INTEGERV),
new GLproperty(GL11.GL_FEEDBACK_BUFFER_TYPE, "GL_FEEDBACK_BUFFER_TYPE", "Type of feedback buffer", "feedback", GL_GET_INTEGERV),
new GLproperty(GL11.GL_FOG, "GL_FOG", "True if fog enabled", "fog/enable", GL_IS_ENABLED),
new GLproperty(GL11.GL_FOG_COLOR, "GL_FOG_COLOR", "Fog color", "fog", GL_GET_FLOATV),
new GLproperty(GL11.GL_FOG_DENSITY, "GL_FOG_DENSITY", "Exponential fog density", "fog", GL_GET_FLOATV),
new GLproperty(GL11.GL_FOG_END, "GL_FOG_END", "Linear fog end", "fog", GL_GET_FLOATV),
new GLproperty(GL11.GL_FOG_HINT, "GL_FOG_HINT", "Fog hint", "hint", GL_GET_INTEGERV),
new GLproperty(GL11.GL_FOG_INDEX, "GL_FOG_INDEX", "Fog index", "fog", GL_GET_FLOATV),
new GLproperty(GL11.GL_FOG_MODE, "GL_FOG_MODE", "Fog mode", "fog", GL_GET_INTEGERV),
new GLproperty(GL11.GL_FOG_START, "GL_FOG_START", "Linear fog start", "fog", GL_GET_FLOATV),
new GLproperty(GL11.GL_FRONT_FACE, "GL_FRONT_FACE", "Polygon front-face CW/CCW indicator", "polygon", GL_GET_INTEGERV),
new GLproperty(GL11.GL_GREEN_BITS, "GL_GREEN_BITS", "Number of bits per green component in color buffers", "capability", GL_GET_INTEGERV),
new GLproperty(GL11.GL_INDEX_ARRAY, "GL_INDEX_ARRAY", "Color-index array enable", "vertex-array", GL_IS_ENABLED),
new GLproperty(GL11.GL_INDEX_ARRAY_POINTER, "GL_INDEX_ARRAY_POINTER", "Pointer to the index array", "vertex-array", "glGetPointerv()"),
new GLproperty(GL11.GL_INDEX_ARRAY_STRIDE, "GL_INDEX_ARRAY_STRIDE", "Stride between color indices", "vertex-array", GL_GET_INTEGERV),
new GLproperty(GL11.GL_INDEX_ARRAY_TYPE, "GL_INDEX_ARRAY_TYPE", "Type of color indices", "vertex-array", GL_GET_INTEGERV),
new GLproperty(GL11.GL_INDEX_BITS, "GL_INDEX_BITS", "Number of bits per index in color buffers", "capability", GL_GET_INTEGERV),
new GLproperty(GL11.GL_INDEX_CLEAR_VALUE, "GL_INDEX_CLEAR_VALUE", "Color-buffer clear value (color-index mode)", "color-buffer", GL_GET_FLOATV),
new GLproperty(GL11.GL_INDEX_LOGIC_OP, "GL_INDEX_LOGIC_OP", "Color index logical operation enabled", "color-buffer/enable", GL_IS_ENABLED),
new GLproperty(GL11.GL_INDEX_MODE, "GL_INDEX_MODE", "True if color buffers store indices", "capability", GL_GET_BOOLEANV),
new GLproperty(GL11.GL_INDEX_OFFSET, "GL_INDEX_OFFSET", "Value of GL_INDEX_OFFSET", "pixel", GL_GET_INTEGERV),
new GLproperty(GL11.GL_INDEX_SHIFT, "GL_INDEX_SHIFT", "Value of GL_INDEX_SHIFT", "pixel", GL_GET_INTEGERV),
new GLproperty(GL11.GL_INDEX_WRITEMASK, "GL_INDEX_WRITEMASK", "Color-index writemask", "color-buffer", GL_GET_INTEGERV),
new GLproperty(GL11.GL_LIGHT0, "GL_LIGHT0", "True if light 0 enabled", "lighting/enable", GL_IS_ENABLED),
new GLproperty(GL11.GL_LIGHT1, "GL_LIGHT1", "True if light 1 enabled", "lighting/enable", GL_IS_ENABLED),
new GLproperty(GL11.GL_LIGHT2, "GL_LIGHT2", "True if light 2 enabled", "lighting/enable", GL_IS_ENABLED),
new GLproperty(GL11.GL_LIGHT3, "GL_LIGHT3", "True if light 3 enabled", "lighting/enable", GL_IS_ENABLED),
new GLproperty(GL11.GL_LIGHT4, "GL_LIGHT4", "True if light 4 enabled", "lighting/enable", GL_IS_ENABLED),
new GLproperty(GL11.GL_LIGHT5, "GL_LIGHT5", "True if light 5 enabled", "lighting/enable", GL_IS_ENABLED),
new GLproperty(GL11.GL_LIGHT6, "GL_LIGHT6", "True if light 6 enabled", "lighting/enable", GL_IS_ENABLED),
new GLproperty(GL11.GL_LIGHT7, "GL_LIGHT7", "True if light 7 enabled", "lighting/enable", GL_IS_ENABLED),
new GLproperty(GL11.GL_LIGHTING, "GL_LIGHTING", "True if lighting is enabled", "lighting/e nable", GL_IS_ENABLED),
new GLproperty(GL11.GL_LIGHT_MODEL_AMBIENT, "GL_LIGHT_MODEL_AMBIENT", "Ambient scene color", "lighting", GL_GET_FLOATV),
new GLproperty(GL11.GL_LIGHT_MODEL_LOCAL_VIEWER, "GL_LIGHT_MODEL_LOCAL_VIEWER", "Viewer is local", "lighting", GL_GET_BOOLEANV),
new GLproperty(GL11.GL_LIGHT_MODEL_TWO_SIDE, "GL_LIGHT_MODEL_TWO_SIDE", "Use two-sided lighting", "lighting", GL_GET_BOOLEANV),
new GLproperty(GL11.GL_LINEAR_ATTENUATION, "GL_LINEAR_ATTENUATION", "Linear attenuation factor", "lighting", "glGetLightfv()"),
new GLproperty(GL11.GL_LINE_SMOOTH, "GL_LINE_SMOOTH", "Line antialiasing on", "line/enable", GL_IS_ENABLED),
new GLproperty(GL11.GL_LINE_SMOOTH_HINT, "GL_LINE_SMOOTH_HINT", "Line smooth hint", "hint", GL_GET_INTEGERV),
new GLproperty(GL11.GL_LINE_STIPPLE, "GL_LINE_STIPPLE", "Line stipple enable", "line/enable", GL_IS_ENABLED),
new GLproperty(GL11.GL_LINE_STIPPLE_PATTERN, "GL_LINE_STIPPLE_PATTERN", "Line stipple", "line", GL_GET_INTEGERV),
new GLproperty(GL11.GL_LINE_STIPPLE_REPEAT, "GL_LINE_STIPPLE_REPEAT", "Line stipple repeat", "line", GL_GET_INTEGERV),
new GLproperty(GL11.GL_LINE_WIDTH, "GL_LINE_WIDTH", "Line width", "line", GL_GET_FLOATV),
new GLproperty(GL11.GL_LINE_WIDTH_GRANULARITY, "GL_LINE_WIDTH_GRANULARITY", "Antialiased line-width granularity", "capability", GL_GET_FLOATV),
new GLproperty(GL11.GL_LINE_WIDTH_RANGE, "GL_LINE_WIDTH_RANGE", "Range (low to high) of antialiased line widths", "capability", GL_GET_FLOATV),
new GLproperty(GL11.GL_LIST_BASE, "GL_LIST_BASE", "Setting of glListBase()", "list", GL_GET_INTEGERV),
new GLproperty(GL11.GL_LIST_INDEX, "GL_LIST_INDEX", "Number of display list under construction; 0 if none", "current", GL_GET_INTEGERV),
new GLproperty(GL11.GL_LIST_MODE, "GL_LIST_MODE", "Mode of display list under construction; undefined if none", "current", GL_GET_INTEGERV),
new GLproperty(GL11.GL_LOGIC_OP_MODE, "GL_LOGIC_OP_MODE", "Logical operation function", "color-buffer", GL_GET_INTEGERV),
new GLproperty(GL11.GL_MAP1_GRID_DOMAIN, "GL_MAP1_GRID_DOMAIN", "1D grid endpoints", "eval", GL_GET_FLOATV),
new GLproperty(GL11.GL_MAP1_GRID_SEGMENTS, "GL_MAP1_GRID_SEGMENTS", "1D grid divisions", "eval", GL_GET_FLOATV),
new GLproperty(GL11.GL_MAP2_GRID_DOMAIN, "GL_MAP2_GRID_DOMAIN", "2D grid endpoints", "eval", GL_GET_FLOATV),
new GLproperty(GL11.GL_MAP2_GRID_SEGMENTS, "GL_MAP2_GRID_SEGMENTS", "2D grid divisions", "eval", GL_GET_FLOATV),
new GLproperty(GL11.GL_MAP_COLOR, "GL_MAP_COLOR", "True if colors are mapped", "pixel", GL_GET_BOOLEANV),
new GLproperty(GL11.GL_MAP_STENCIL, "GL_MAP_STENCIL", "True if stencil values are mapped", "pixel", GL_GET_BOOLEANV),
new GLproperty(GL11.GL_MATRIX_MODE, "GL_MATRIX_MODE", "Current matrix mode", "transform", GL_GET_INTEGERV),
new GLproperty(GL11.GL_MAX_ATTRIB_STACK_DEPTH, "GL_MAX_ATTRIB_STACK_DEPTH", "Maximum depth of the attribute stack", "capability", GL_GET_INTEGERV),
new GLproperty(GL11.GL_MAX_CLIENT_ATTRIB_STACK_DEPTH, "GL_MAX_CLIENT_ATTRIB_STACK_DEPTH", "Maximum depth of the client attribute stack", "capability", GL_GET_INTEGERV),
new GLproperty(GL11.GL_MAX_CLIP_PLANES, "GL_MAX_CLIP_PLANES", "Maximum number of user clipping planes", "capability", GL_GET_INTEGERV),
new GLproperty(GL11.GL_MAX_EVAL_ORDER, "GL_MAX_EVAL_ORDER", "Maximum evaluator polynomial order", "capability", GL_GET_INTEGERV),
new GLproperty(GL11.GL_MAX_LIGHTS, "GL_MAX_LIGHTS", "Maximum number of lights", "capability", GL_GET_INTEGERV),
new GLproperty(GL11.GL_MAX_LIST_NESTING, "GL_MAX_LIST_NESTING", "Maximum display-list call nesting", "capability", GL_GET_INTEGERV),
new GLproperty(GL11.GL_MAX_MODELVIEW_STACK_DEPTH, "GL_MAX_MODELVIEW_STACK_DEPTH", "Maximum modelview-matrix stack depth", "capability", GL_GET_INTEGERV),
new GLproperty(GL11.GL_MAX_NAME_STACK_DEPTH, "GL_MAX_NAME_STACK_DEPTH", "Maximum selection-name stack depth", "capability", GL_GET_INTEGERV),
new GLproperty(GL11.GL_MAX_PIXEL_MAP_TABLE, "GL_MAX_PIXEL_MAP_TABLE", "Maximum size of a glPixelMap() translation table", "capability", GL_GET_INTEGERV),
new GLproperty(GL11.GL_MAX_PROJECTION_STACK_DEPTH, "GL_MAX_PROJECTION_STACK_DEPTH", "Maximum projection-matrix stack depth", "capability", GL_GET_INTEGERV),
new GLproperty(GL11.GL_MAX_TEXTURE_SIZE, "GL_MAX_TEXTURE_SIZE", "See discussion in Texture Proxy in Chapter 9", "capability", GL_GET_INTEGERV),
new GLproperty(GL11.GL_MAX_TEXTURE_STACK_DEPTH, "GL_MAX_TEXTURE_STACK_DEPTH", "Maximum depth of texture matrix stack", "capability", GL_GET_INTEGERV),
new GLproperty(GL11.GL_MAX_VIEWPORT_DIMS, "GL_MAX_VIEWPORT_DIMS", "Maximum viewport dimensions", "capability", GL_GET_INTEGERV),
new GLproperty(GL11.GL_MODELVIEW_MATRIX, "GL_MODELVIEW_MATRIX", "Modelview matrix stack", "matrix", GL_GET_FLOATV),
new GLproperty(GL11.GL_MODELVIEW_STACK_DEPTH, "GL_MODELVIEW_STACK_DEPTH", "Modelview matrix stack pointer", "matrix", GL_GET_INTEGERV),
new GLproperty(GL11.GL_NAME_STACK_DEPTH, "GL_NAME_STACK_DEPTH", "Name stack depth", "current", GL_GET_INTEGERV),
new GLproperty(GL11.GL_NORMALIZE, "GL_NORMALIZE", "Current normal normalization on/off", "transform/ enable", GL_IS_ENABLED),
new GLproperty(GL11.GL_NORMAL_ARRAY, "GL_NORMAL_ARRAY", "Normal array enable", "vertex-array", GL_IS_ENABLED),
new GLproperty(GL11.GL_NORMAL_ARRAY_POINTER, "GL_NORMAL_ARRAY_POINTER", "Pointer to the normal array", "vertex-array", "glGetPointerv()"),
new GLproperty(GL11.GL_NORMAL_ARRAY_STRIDE, "GL_NORMAL_ARRAY_STRIDE", "Stride between normals", "vertex-array", GL_GET_INTEGERV),
new GLproperty(GL11.GL_NORMAL_ARRAY_TYPE, "GL_NORMAL_ARRAY_TYPE", "Type of normal coordinates", "vertex-array", GL_GET_INTEGERV),
new GLproperty(GL11.GL_OBJECT_PLANE, "GL_OBJECT_PLANE", "Texgen object linear coefficients", "texture", "glGetTexGenfv()"),
new GLproperty(GL11.GL_ORDER, "GL_ORDER", "1D map order", "capability", "glGetMapiv()"),
new GLproperty(GL11.GL_ORDER, "GL_ORDER", "2D map orders", "capability", "glGetMapiv()"),
new GLproperty(GL11.GL_PACK_ALIGNMENT, "GL_PACK_ALIGNMENT", "Value of GL_PACK_ALIGNMENT", "pixel-store", GL_GET_INTEGERV),
new GLproperty(GL11.GL_PACK_LSB_FIRST, "GL_PACK_LSB_FIRST", "Value of GL_PACK_LSB_FIRST", "pixel-store", GL_GET_BOOLEANV),
new GLproperty(GL11.GL_PACK_ROW_LENGTH, "GL_PACK_ROW_LENGTH", "Value of GL_PACK_ROW_LENGTH", "pixel-store", GL_GET_INTEGERV),
new GLproperty(GL11.GL_PACK_SKIP_PIXELS, "GL_PACK_SKIP_PIXELS", "Value of GL_PACK_SKIP_PIXELS", "pixel-store", GL_GET_INTEGERV),
new GLproperty(GL11.GL_PACK_SKIP_ROWS, "GL_PACK_SKIP_ROWS", "Value of GL_PACK_SKIP_ROWS", "pixel-store", GL_GET_INTEGERV),
new GLproperty(GL11.GL_PACK_SWAP_BYTES, "GL_PACK_SWAP_BYTES", "Value of GL_PACK_SWAP_BYTES", "pixel-store", GL_GET_BOOLEANV),
new GLproperty(GL11.GL_PERSPECTIVE_CORRECTION_HINT, "GL_PERSPECTIVE_CORRECTION_HINT", "Perspective correction hint", "hint", GL_GET_INTEGERV),
new GLproperty(GL11.GL_POINT_SIZE, "GL_POINT_SIZE", "Point size", "point", GL_GET_FLOATV),
new GLproperty(GL11.GL_POINT_SIZE_GRANULARITY, "GL_POINT_SIZE_GRANULARITY", "Antialiased point-size granularity", "capability", GL_GET_FLOATV),
new GLproperty(GL11.GL_POINT_SIZE_RANGE, "GL_POINT_SIZE_RANGE", "Range (low to high) of antialiased point sizes", "capability", GL_GET_FLOATV),
new GLproperty(GL11.GL_POINT_SMOOTH, "GL_POINT_SMOOTH", "Point antialiasing on", "point/enable", GL_IS_ENABLED),
new GLproperty(GL11.GL_POINT_SMOOTH_HINT, "GL_POINT_SMOOTH_HINT", "Point smooth hint", "hint", GL_GET_INTEGERV),
new GLproperty(GL11.GL_POLYGON_MODE, "GL_POLYGON_MODE", "Polygon rasterization mode (front and back)", "polygon", GL_GET_INTEGERV),
new GLproperty(GL11.GL_POLYGON_OFFSET_FACTOR, "GL_POLYGON_OFFSET_FACTOR", "Polygon offset factor", "polygon", GL_GET_FLOATV),
new GLproperty(GL11.GL_POLYGON_OFFSET_FILL, "GL_POLYGON_OFFSET_FILL", "Polygon offset enable for GL_FILL mode rasterization", "polygon/enable", GL_IS_ENABLED),
new GLproperty(GL11.GL_POLYGON_OFFSET_LINE, "GL_POLYGON_OFFSET_LINE", "Polygon offset enable for GL_LINE mode rasterization", "polygon/enable", GL_IS_ENABLED),
new GLproperty(GL11.GL_POLYGON_OFFSET_POINT, "GL_POLYGON_OFFSET_POINT", "Polygon offset enable for GL_POINT mode rasterization", "polygon/enable", GL_IS_ENABLED),
new GLproperty(GL11.GL_POLYGON_SMOOTH, "GL_POLYGON_SMOOTH", "Polygon antialiasing on", "polygon/enable", GL_IS_ENABLED),
new GLproperty(GL11.GL_POLYGON_SMOOTH_HINT, "GL_POLYGON_SMOOTH_HINT", "Polygon smooth hint", "hint", GL_GET_INTEGERV),
new GLproperty(GL11.GL_POLYGON_STIPPLE, "GL_POLYGON_STIPPLE", "Polygon stipple enable", "polygon/enable", GL_IS_ENABLED),
new GLproperty(GL11.GL_POSITION, "GL_POSITION", "Position of light i", "lighting", "glGetLightfv()"),
new GLproperty(GL11.GL_PROJECTION_MATRIX, "GL_PROJECTION_MATRIX", "Projection matrix stack", "matrix", GL_GET_FLOATV),
new GLproperty(GL11.GL_PROJECTION_STACK_DEPTH, "GL_PROJECTION_STACK_DEPTH", "Projection matrix stack pointer", "matrix", GL_GET_INTEGERV),
new GLproperty(GL11.GL_QUADRATIC_ATTENUATION, "GL_QUADRATIC_ATTENUATION", "Quadratic attenuation factor", "lighting", "glGetLightfv()"),
new GLproperty(GL11.GL_READ_BUFFER, "GL_READ_BUFFER", "Read source buffer", "pixel", GL_GET_INTEGERV),
new GLproperty(GL11.GL_RED_BITS, "GL_RED_BITS", "Number of bits per red component in color buffers", "capability", GL_GET_INTEGERV),
new GLproperty(GL11.GL_RENDER_MODE, "GL_RENDER_MODE", "glRenderMode() setting", "current", GL_GET_INTEGERV),
new GLproperty(GL11.GL_RGBA_MODE, "GL_RGBA_MODE", "True if color buffers store RGBA", "capability", GL_GET_BOOLEANV),
new GLproperty(GL11.GL_SCISSOR_BOX, "GL_SCISSOR_BOX", "Scissor box", "scissor", GL_GET_INTEGERV),
new GLproperty(GL11.GL_SCISSOR_TEST, "GL_SCISSOR_TEST", "Scissoring enabled", "scissor/enable", GL_IS_ENABLED),
new GLproperty(GL11.GL_SELECTION_BUFFER_POINTER, "GL_SELECTION_BUFFER_POINTER", "Pointer to selection buffer", "select", "glGetPointerv()"),
new GLproperty(GL11.GL_SELECTION_BUFFER_SIZE, "GL_SELECTION_BUFFER_SIZE", "Size of selection buffer", "select", GL_GET_INTEGERV),
new GLproperty(GL11.GL_SHADE_MODEL, "GL_SHADE_MODEL", "glShadeModel() setting", "lighting", GL_GET_INTEGERV),
new GLproperty(GL11.GL_SHININESS, "GL_SHININESS", "Specular exponent of material", "lighting", "glGetMaterialfv()"),
new GLproperty(GL11.GL_SPECULAR, "GL_SPECULAR", "Specular intensity of light i", "lighting", "glGetLightfv()"),
new GLproperty(GL11.GL_SPECULAR, "GL_SPECULAR", "Specular material color", "lighting", "glGetMaterialfv()"),
new GLproperty(GL11.GL_SPOT_CUTOFF, "GL_SPOT_CUTOFF", "Spotlight angle of light i", "lighting", "glGetLightfv()"),
new GLproperty(GL11.GL_SPOT_DIRECTION, "GL_SPOT_DIRECTION", "Spotlight direction of light i", "lighting", "glGetLightfv()"),
new GLproperty(GL11.GL_SPOT_EXPONENT, "GL_SPOT_EXPONENT", "Spotlight exponent of light i", "lighting", "glGetLightfv()"),
new GLproperty(GL11.GL_STENCIL_BITS, "GL_STENCIL_BITS", "Number of stencil bitplanes", "capability", GL_GET_INTEGERV),
new GLproperty(GL11.GL_STENCIL_CLEAR_VALUE, "GL_STENCIL_CLEAR_VALUE", "Stencil-buffer clear value", "stencil-buffer", GL_GET_INTEGERV),
new GLproperty(GL11.GL_STENCIL_FAIL, "GL_STENCIL_FAIL", "Stencil fail action", "stencil-buffer", GL_GET_INTEGERV),
new GLproperty(GL11.GL_STENCIL_FUNC, "GL_STENCIL_FUNC", "Stencil function", "stencil-buffer", GL_GET_INTEGERV),
new GLproperty(GL11.GL_STENCIL_PASS_DEPTH_FAIL, "GL_STENCIL_PASS_DEPTH_FAIL", "Stencil depth buffer fail action", "stencil-buffer", GL_GET_INTEGERV),
new GLproperty(GL11.GL_STENCIL_PASS_DEPTH_PASS, "GL_STENCIL_PASS_DEPTH_PASS", "Stencil depth buffer pass action", "stencil-buffer", GL_GET_INTEGERV),
new GLproperty(GL11.GL_STENCIL_REF, "GL_STENCIL_REF", "Stencil reference value", "stencil-buffer", GL_GET_INTEGERV),
new GLproperty(GL11.GL_STENCIL_TEST, "GL_STENCIL_TEST", "Stenciling enabled", "stencil-buffer/enable", GL_IS_ENABLED),
new GLproperty(GL11.GL_STENCIL_VALUE_MASK, "GL_STENCIL_VALUE_MASK", "Stencil mask", "stencil-buffer", GL_GET_INTEGERV),
new GLproperty(GL11.GL_STENCIL_WRITEMASK, "GL_STENCIL_WRITEMASK", "Stencil-buffer writemask", "stencil-buffer", GL_GET_INTEGERV),
new GLproperty(GL11.GL_STEREO, "GL_STEREO", "True if left and right buffers exist", "capability", GL_GET_BOOLEANV),
new GLproperty(GL11.GL_SUBPIXEL_BITS, "GL_SUBPIXEL_BITS", "Number of bits of subpixel precision in x and y", "capability", GL_GET_INTEGERV),
new GLproperty(GL11.GL_TEXTURE, "GL_TEXTURE", "x-D texture image at level of detail i", "UNUSED", "glGetTexImage()"),
new GLproperty(GL11.GL_TEXTURE_1D, "GL_TEXTURE_1D", "True if 1-D texturing enabled ", "texture/enable", GL_IS_ENABLED),
new GLproperty(GL11.GL_TEXTURE_2D, "GL_TEXTURE_2D", "True if 2-D texturing enabled ", "texture/enable", GL_IS_ENABLED),
new GLproperty(GL11.GL_TEXTURE_ALPHA_SIZE, "GL_TEXTURE_ALPHA_SIZE", "x-D texture image i's alpha resolution", "UNUSED", "glGetTexLevelParameter*()"),
new GLproperty(GL11.GL_TEXTURE_BINDING_1D, "GL_TEXTURE_BINDING_1D", "Texture object bound to GL_TEXTURE_1D", "texture", GL_GET_INTEGERV),
new GLproperty(GL11.GL_TEXTURE_BINDING_2D, "GL_TEXTURE_BINDING_2D", "Texture object bound to GL_TEXTURE_2D", "texture", GL_GET_INTEGERV),
new GLproperty(GL11.GL_TEXTURE_BLUE_SIZE, "GL_TEXTURE_BLUE_SIZE", "x-D texture image i's blue resolution", "UNUSED", "glGetTexLevelParameter*()"),
new GLproperty(GL11.GL_TEXTURE_BORDER, "GL_TEXTURE_BORDER", "x-D texture image i's border width", "UNUSED", "glGetTexLevelParameter*()"),
new GLproperty(GL11.GL_TEXTURE_BORDER_COLOR, "GL_TEXTURE_BORDER_COLOR", "Texture border color", "texture", "glGetTexParameter*()"),
new GLproperty(GL11.GL_TEXTURE_COORD_ARRAY, "GL_TEXTURE_COORD_ARRAY", "Texture coordinate array enable", "vertex-array", GL_IS_ENABLED),
new GLproperty(GL11.GL_TEXTURE_COORD_ARRAY_POINTER, "GL_TEXTURE_COORD_ARRAY_POINTER", "Pointer to the texture coordinate array", "vertex-array", "glGetPointerv()"),
new GLproperty(GL11.GL_TEXTURE_COORD_ARRAY_SIZE, "GL_TEXTURE_COORD_ARRAY_SIZE", "Texture coordinates per element", "vertex-array", GL_GET_INTEGERV),
new GLproperty(GL11.GL_TEXTURE_COORD_ARRAY_STRIDE, "GL_TEXTURE_COORD_ARRAY_STRIDE", "Stride between texture coordinates", "vertex-array", GL_GET_INTEGERV),
new GLproperty(GL11.GL_TEXTURE_COORD_ARRAY_TYPE, "GL_TEXTURE_COORD_ARRAY_TYPE", "Type of texture coordinates", "vertex-array", GL_GET_INTEGERV),
new GLproperty(GL11.GL_TEXTURE_ENV_COLOR, "GL_TEXTURE_ENV_COLOR", "Texture environment color", "texture", "glGetTexEnvfv()"),
new GLproperty(GL11.GL_TEXTURE_ENV_MODE, "GL_TEXTURE_ENV_MODE", "Texture application function", "texture", "glGetTexEnviv()"),
new GLproperty(GL11.GL_TEXTURE_GEN_MODE, "GL_TEXTURE_GEN_MODE", "Function used for texgen", "texture", "glGetTexGeniv()"),
new GLproperty(GL11.GL_TEXTURE_GEN_Q, "GL_TEXTURE_GEN_Q", "Texgen enabled (x is S, T, R, or Q)", "texture/enable", GL_IS_ENABLED),
new GLproperty(GL11.GL_TEXTURE_GEN_R, "GL_TEXTURE_GEN_R", "Texgen enabled (x is S, T, R, or Q)", "texture/enable", GL_IS_ENABLED),
new GLproperty(GL11.GL_TEXTURE_GEN_S, "GL_TEXTURE_GEN_S", "Texgen enabled (x is S, T, R, or Q)", "texture/enable", GL_IS_ENABLED),
new GLproperty(GL11.GL_TEXTURE_GEN_T, "GL_TEXTURE_GEN_T", "Texgen enabled (x is S, T, R, or Q)", "texture/enable", GL_IS_ENABLED),
new GLproperty(GL11.GL_TEXTURE_GREEN_SIZE, "GL_TEXTURE_GREEN_SIZE", "x-D texture image i's green resolution", "UNUSED", "glGetTexLevelParameter*()"),
new GLproperty(GL11.GL_TEXTURE_HEIGHT, "GL_TEXTURE_HEIGHT", "x-D texture image i's height", "UNUSED", "glGetTexLevelParameter*()"),
new GLproperty(GL11.GL_TEXTURE_INTENSITY_SIZE, "GL_TEXTURE_INTENSITY_SIZE", "x-D texture image i's intensity resolution", "UNUSED", "glGetTexLevelParameter*()"),
new GLproperty(GL11.GL_TEXTURE_LUMINANCE_SIZE, "GL_TEXTURE_LUMINANCE_SIZE", "x-D texture image i's luminance resolution", "UNUSED", "glGetTexLevelParameter*()"),
new GLproperty(GL11.GL_TEXTURE_MAG_FILTER, "GL_TEXTURE_MAG_FILTER", "Texture magnification function", "texture", "glGetTexParameter*()"),
new GLproperty(GL11.GL_TEXTURE_MATRIX, "GL_TEXTURE_MATRIX", "Texture matrix stack", "matrix", GL_GET_FLOATV),
new GLproperty(GL11.GL_TEXTURE_MIN_FILTER, "GL_TEXTURE_MIN_FILTER", "Texture minification function", "texture", "glGetTexParameter*()"),
new GLproperty(GL11.GL_TEXTURE_PRIORITY, "GL_TEXTURE_PRIORITY", "Texture object priority", "texture", "glGetTexParameter*()"),
new GLproperty(GL11.GL_TEXTURE_RED_SIZE, "GL_TEXTURE_RED_SIZE", "x-D texture image i's red resolution", "UNUSED", "glGetTexLevelParameter*()"),
new GLproperty(GL11.GL_TEXTURE_STACK_DEPTH, "GL_TEXTURE_STACK_DEPTH", "Texture matrix stack pointer", "matrix", GL_GET_INTEGERV),
new GLproperty(GL11.GL_TEXTURE_WIDTH, "GL_TEXTURE_WIDTH", "x-D texture image i's width", "UNUSED", "glGetTexLevelParameter*()"),
new GLproperty(GL11.GL_TEXTURE_WRAP_S, "GL_TEXTURE_WRAP_S", "Texture wrap mode (x is S or T)", "texture", "glGetTexParameter*()"),
new GLproperty(GL11.GL_TEXTURE_WRAP_T, "GL_TEXTURE_WRAP_T", "Texture wrap mode (x is S or T)", "texture", "glGetTexParameter*()"),
new GLproperty(GL11.GL_UNPACK_ALIGNMENT, "GL_UNPACK_ALIGNMENT", "Value of GL_UNPACK_ALIGNMENT", "pixel-store", GL_GET_INTEGERV),
new GLproperty(GL11.GL_UNPACK_LSB_FIRST, "GL_UNPACK_LSB_FIRST", "Value of GL_UNPACK_LSB_FIRST", "pixel-store", GL_GET_BOOLEANV),
new GLproperty(GL11.GL_UNPACK_ROW_LENGTH, "GL_UNPACK_ROW_LENGTH", "Value of GL_UNPACK_ROW_LENGTH", "pixel-store", GL_GET_INTEGERV),
new GLproperty(GL11.GL_UNPACK_SKIP_PIXELS, "GL_UNPACK_SKIP_PIXELS", "Value of GL_UNPACK_SKIP_PIXELS", "pixel-store", GL_GET_INTEGERV),
new GLproperty(GL11.GL_UNPACK_SKIP_ROWS, "GL_UNPACK_SKIP_ROWS", "Value of GL_UNPACK_SKIP_ROWS", "pixel-store", GL_GET_INTEGERV),
new GLproperty(GL11.GL_UNPACK_SWAP_BYTES, "GL_UNPACK_SWAP_BYTES", "Value of GL_UNPACK_SWAP_BYTES", "pixel-store", GL_GET_BOOLEANV),
new GLproperty(GL11.GL_VERTEX_ARRAY, "GL_VERTEX_ARRAY", "Vertex array enable", "vertex-array", GL_IS_ENABLED),
new GLproperty(GL11.GL_VERTEX_ARRAY_POINTER, "GL_VERTEX_ARRAY_POINTER", "Pointer to the vertex array", "vertex-array", "glGetPointerv()"),
new GLproperty(GL11.GL_VERTEX_ARRAY_SIZE, "GL_VERTEX_ARRAY_SIZE", "Coordinates per vertex", "vertex-array", GL_GET_INTEGERV),
new GLproperty(GL11.GL_VERTEX_ARRAY_STRIDE, "GL_VERTEX_ARRAY_STRIDE", "Stride between vertices", "vertex-array", GL_GET_INTEGERV),
new GLproperty(GL11.GL_VERTEX_ARRAY_TYPE, "GL_VERTEX_ARRAY_TYPE", "Type of vertex coordinates", "vertex-array", GL_GET_INTEGERV),
new GLproperty(GL11.GL_VIEWPORT, "GL_VIEWPORT", "Viewport origin and extent", "viewport", GL_GET_INTEGERV),
new GLproperty(GL11.GL_ZOOM_X, "GL_ZOOM_X", "x zoom factor", "pixel", GL_GET_FLOATV),
new GLproperty(GL11.GL_ZOOM_Y, "GL_ZOOM_Y", "y zoom factor", "pixel", GL_GET_FLOATV),
};
public static void dumpToFile(Consumer<Consumer<String>> dumper, String fileName) {
final List<String> lines = new ArrayList<>();
dumper.accept(lines::add);
try {
FileUtils.writeLines(new File(fileName), lines);
} catch (IOException e) {
LOGGER.error("Failed to write file");
e.printStackTrace();
}
}
public static void dumpStateToFile() {
dumpToFile(p -> dumpState(p, false), "gl-dump-state.txt");
}
public static void dumpGLSMStateToFile() {
dumpToFile(p -> dumpState(p, true), "glsm-dump-state.txt");
}
public static void dumpState(boolean glsm) {
dumpState(LINE_LOGGER, glsm);
}
public static void dumpState(Consumer<String> printer, boolean glsm) {
for (int i = 0; i < instance.propertyList.length; ++i) {
final GLproperty gLProperty = instance.propertyList[i];
printer.accept(gLProperty.name + ":" + gLProperty.getAsString(glsm) + " (" + gLProperty.description + ")");
}
}
public static void dumpIsEnabledToFile(boolean glsm) {
dumpToFile(p -> dumpIsEnabled(p, glsm), (glsm ? "glsm" : "gl") + "-dump-enabled.txt");
}
public static void dumpIsEnabled(boolean glsm) {
dumpIsEnabled(LINE_LOGGER, glsm);
}
public static void dumpIsEnabled(Consumer<String> printer, boolean glsm) {
for (int i = 0; i < instance.propertyList.length; ++i) {
final GLproperty gLProperty = instance.propertyList[i];
if (gLProperty.fetchCommand.equals(GL_IS_ENABLED)) {
printer.accept(gLProperty.name + ":");
printer.accept("" + gLProperty.getAsString(glsm));
printer.accept(" (" + gLProperty.description + ")");
}
}
}
public static void dumpTypeToFile(String type, boolean glsm) {
dumpToFile(p -> dumpType(type, p, glsm), (glsm ? "glsm" : "gl") + "-dump-type-" + type + ".txt");
}
public static void dumpType(String type, boolean glsm) {
dumpType(type, LINE_LOGGER, glsm);
}
public static void dumpType(String type, Consumer<String> printer, boolean glsm) {
for (int i = 0; i < instance.propertyList.length; ++i) {
final GLproperty gLProperty = instance.propertyList[i];
if (gLProperty.category.equals(type)) {
printer.accept(gLProperty.name + ":");
printer.accept(gLProperty.getAsString(glsm));
printer.accept(" (" + gLProperty.description + ")");
}
}
}
public static String getGLSMErrorLog() {
return getGLSMErrorLog(null, false, false);
}
// Re-entrancy guard - getGLSMErrorLog calls glActiveTexture which could trigger checkGLSMOnce
private static boolean inCheck = false;
/**
* Enhanced GLSM error logging with context, stack trace, and first-occurrence filtering.
*
* @param context Optional context string to include in error messages (e.g., "During rendering")
* @param logStacktrace If true, includes the current stack trace in the error output
* @param onlyFirstOccurrence If true, only logs each unique error once
* @return Error log string if mismatches found, null otherwise
*/
public static String getGLSMErrorLog(String context, boolean logStacktrace, boolean onlyFirstOccurrence) {
if (inCheck) return null;
if (!GLStateManager.isCachingEnabled() || GLStateManager.isRecordingDisplayList()) {
return null;
}
inCheck = true;
try {
String group = "checkGLSM" + (context == null ? "" : " " + context);
GLDebug.pushGroup(group);
final StringBuilder error = new StringBuilder();
boolean mismatch = false;
if (context != null && !context.isEmpty()) {
error.append("[").append(context).append("] ");
}
for (int i = 0; i < instance.propertyList.length; ++i) {
final GLproperty gLProperty = instance.propertyList[i];
if (gLProperty.fetchCommand.equals(GL_GET_FLOATV) && gLProperty.name.endsWith("_MATRIX")) {
final Matrix4f cached = gLProperty.getAsMatrix4f(true);
final Matrix4f uncached = gLProperty.getAsMatrix4f(false);
// Skip comparison if either matrix is degenerate (contains NaN/Infinity) these represent invalid GL state from bad parameters, not cache bugs
if (isMatrixDegenerate(cached) || isMatrixDegenerate(uncached)) continue;
if (!matricesEquivalent(cached, uncached, 0.001f)) {
final String errorKey = "MATRIX:" + gLProperty.name;
if (!onlyFirstOccurrence || seenErrors.add(errorKey)) {
final String errorMsg = "GLSM mismatch: " + gLProperty.name + "\ncached:\n" + cached + "uncached:\n" + uncached;
LOGGER.error(errorMsg);
error.append(errorMsg).append('\n');
mismatch = true;
}
}
} else {
final String cached = gLProperty.getAsString(true);
final String uncached = gLProperty.getAsString(false);
if (!cached.equals(uncached)) {
final String errorKey = "PROPERTY:" + gLProperty.name + ":" + cached + ":" + uncached;
if (!onlyFirstOccurrence || seenErrors.add(errorKey)) {
error.append("GLSM mismatch: ").append(gLProperty.name).append(" cached: ").append(cached).append(" uncached: ").append(uncached);
error.append('\n');
mismatch = true;
}
}
}
}
final TextureUnitArray textureUnits = GLStateManager.getTextures();
final int currentActiveTexture = GLStateManager.getActiveTextureUnit();
// Check GL_ACTIVE_TEXTURE
final int glActiveUnit = GL11.glGetInteger(GL13.GL_ACTIVE_TEXTURE) - GL13.GL_TEXTURE0;
if (glActiveUnit != currentActiveTexture) {
final String errorKey = "ACTIVE_TEXTURE:" + currentActiveTexture + ":" + glActiveUnit;
if (!onlyFirstOccurrence || seenErrors.add(errorKey)) {
error.append("GLSM mismatch: GL_ACTIVE_TEXTURE cached: ").append(currentActiveTexture)
.append(" uncached: ").append(glActiveUnit).append('\n');
mismatch = true;
}
}
// Check per-unit texture state
for (int i = 0; i < textureUnits.textureMatricies.length; i++) {
GLStateManager.glActiveTexture(GL13.GL_TEXTURE0 + i);
// Check GL_TEXTURE_2D enabled
final boolean cachedEnabled = textureUnits.getTextureUnitStates(i).isEnabled();
final boolean uncachedEnabled = GL11.glIsEnabled(GL11.GL_TEXTURE_2D);
if (cachedEnabled != uncachedEnabled) {
final String errorKey = "TEXTURE_2D:" + i + ":" + cachedEnabled + ":" + uncachedEnabled;
if (!onlyFirstOccurrence || seenErrors.add(errorKey)) {
error.append("GLSM mismatch: GL_TEXTURE_2D cached: ").append(cachedEnabled)
.append(" uncached: ").append(uncachedEnabled)
.append(", texture unit: GL_TEXTURE").append(i).append('\n');
mismatch = true;
}
}
// Check GL_TEXTURE_BINDING_2D
final int cachedBinding = textureUnits.getTextureUnitBindings(i).getBinding();
final int uncachedBinding = GL11.glGetInteger(GL11.GL_TEXTURE_BINDING_2D);
if (cachedBinding != uncachedBinding) {
final String errorKey = "TEXTURE_BINDING_2D:" + i + ":" + cachedBinding + ":" + uncachedBinding;
if (!onlyFirstOccurrence || seenErrors.add(errorKey)) {
error.append("GLSM mismatch: GL_TEXTURE_BINDING_2D cached: ").append(cachedBinding)
.append(" uncached: ").append(uncachedBinding)
.append(", texture unit: GL_TEXTURE").append(i).append('\n');
mismatch = true;
}
}
}
GLStateManager.glActiveTexture(GL13.GL_TEXTURE0 + currentActiveTexture);
// Add stack trace if requested
if (mismatch && logStacktrace) {
error.append("\nStack trace:\n");
final StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
for (int i = 2; i < stackTrace.length; i++) {
error.append(" at ").append(stackTrace[i].toString()).append('\n');
}
}
GLDebug.popGroup();
return mismatch ? error.toString() : null;
} finally {
inCheck = false;
}
}
public static boolean checkGLSMOnce(String context) {
final String output = getGLSMErrorLog(context, true, true);
if (output != null) {
// Only log on actual mismatch
LOGGER.error("[{}] MISMATCH thread={}\n{}", context, Thread.currentThread().getName(), output);
return false;
}
return true;
}
/**
* Check if a matrix contains any non-finite values (NaN or Infinity).
* Such matrices represent invalid/degenerate GL state (e.g., zero near/far in projection).
*/
private static boolean isMatrixDegenerate(Matrix4f matrix) {
for (int col = 0; col < 4; col++) {
for (int row = 0; row < 4; row++) {
if (!Float.isFinite(matrix.get(col, row))) {
return true;
}
}
}
return false;
}
/**
* Compare two matrices with tolerance for NaN/Infinity.
* Treats NaN == NaN and Infinity == Infinity as equal (both are degenerate states).
* For finite values, uses epsilon comparison.
*/
private static boolean matricesEquivalent(Matrix4f a, Matrix4f b, float epsilon) {
// Compare all 16 elements
for (int col = 0; col < 4; col++) {
for (int row = 0; row < 4; row++) {
final float aVal = a.get(col, row);
final float bVal = b.get(col, row);
// If both are non-finite (NaN or Infinity), consider them equal
if (!Float.isFinite(aVal) && !Float.isFinite(bVal)) {
// Both non-finite: check if both NaN or both same Infinity
if (Float.isNaN(aVal) && Float.isNaN(bVal)) continue;
if (Float.isInfinite(aVal) && Float.isInfinite(bVal)) {
// Check same sign of infinity
if ((aVal > 0) == (bVal > 0)) continue;
}
return false; // Different non-finite values
}
// If one is finite and other is not, they differ
if (Float.isFinite(aVal) != Float.isFinite(bVal)) {
return false;
}
// Both finite: use epsilon comparison
if (Math.abs(aVal - bVal) > epsilon) {
return false;
}
}
}
return true;
}
public static void checkGLSM() {
final String output = getGLSMErrorLog();
if (output == null) {
LOGGER.info("GLSM state matches!");
} else {
LOGGER.error(output);
}
}
public static void copyTexture(ResourceLocation resource, File output) {
final Object object = Minecraft.getMinecraft().renderEngine.mapTextureObjects.get(resource);
if (object != null) {
copyTexture(((ITextureObject) object).getGlTextureId(), output);
}
}
public static void copyTexture(int textureID, File output) {
GLStateManager.glBindTexture(GL11.GL_TEXTURE_2D, textureID);
int width = GL11.glGetTexLevelParameteri(GL11.GL_TEXTURE_2D, 0, GL11.GL_TEXTURE_WIDTH);
int height = GL11.glGetTexLevelParameteri(GL11.GL_TEXTURE_2D, 0, GL11.GL_TEXTURE_HEIGHT);
BufferedImage bufferedimage = new BufferedImage(width, height, 1);
final int[] pixelValues = ((DataBufferInt) bufferedimage.getRaster().getDataBuffer()).getData();
IntBuffer pixelBuffer = BufferUtils.createIntBuffer(pixelValues.length);
GL11.glGetTexImage(GL11.GL_TEXTURE_2D, 0, GL12.GL_BGRA, GL12.GL_UNSIGNED_INT_8_8_8_8_REV, pixelBuffer);
pixelBuffer.get(pixelValues);
// Flip texture
final int halfHeight = height / 2;
final int[] rowBuffer = new int[width];
for (int y = 0; y < halfHeight; y++) {
final int top = y * width;
final int bottom = (height - 1 - y) * width;
System.arraycopy(pixelValues, top, rowBuffer, 0, width);
System.arraycopy(pixelValues, bottom, pixelValues, top, width);
System.arraycopy(rowBuffer, 0, pixelValues, bottom, width);
}
File dir = output.getParentFile();
dir.mkdirs();
copyBufferedImageToFile(bufferedimage, output);
bufferedimage.flush();
}
private static void copyBufferedImageToFile(BufferedImage image, File file) {
try {
ImageIO.write(image, "png", file);
} catch (Exception e) {
e.printStackTrace();
}
}
}
@@ -334,6 +334,7 @@ public class BatchingFontRenderer {
batchCommands.sort(FontDrawCmd.DRAW_ORDER_COMPARATOR);
final boolean isTextureEnabledBefore = GLStateManager.glIsEnabled(GL11.GL_TEXTURE_2D);
final boolean isBlendEnabledBefore = GLStateManager.glIsEnabled(GL11.GL_BLEND);
final int boundTextureBefore = GLStateManager.glGetInteger(GL11.GL_TEXTURE_BINDING_2D);
boolean textureChanged = false;
@@ -417,6 +418,9 @@ public class BatchingFontRenderer {
if (isTextureEnabledBefore) {
GLStateManager.glEnable(GL11.GL_TEXTURE_2D);
}
if (!isBlendEnabledBefore) {
GLStateManager.disableBlend();
}
if (textureChanged) {
GLStateManager.glBindTexture(GL11.GL_TEXTURE_2D, boundTextureBefore);
}
@@ -5,8 +5,6 @@ import com.mitchej123.glsm.RenderSystemService;
import org.joml.Matrix4f;
import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL20;
import java.nio.FloatBuffer;
public class AngelicaRenderSystemService implements RenderSystemService {
@@ -115,17 +113,17 @@ public class AngelicaRenderSystemService implements RenderSystemService {
@Override
public void glUniform1i(int location, int value) {
GL20.glUniform1i(location, value);
GLStateManager.glUniform1i(location, value);
}
@Override
public void glUniformMatrix3(int location, boolean transpose, FloatBuffer value) {
GL20.glUniformMatrix3(location, transpose, value);
GLStateManager.glUniformMatrix3(location, transpose, value);
}
@Override
public void glUniformMatrix4(int location, boolean transpose, FloatBuffer value) {
GL20.glUniformMatrix4(location, transpose, value);
GLStateManager.glUniformMatrix4(location, transpose, value);
}
// ===================== THREAD ASSERTIONS =====================
@@ -99,10 +99,14 @@ public class DeferredDrawBatcher {
totalBytes += e.byteLength();
totalVertices += e.vertexCount();
subEnd++;
// Don't try to merge strips, fans, loops or polygons
if (drawMode == GL11.GL_TRIANGLE_STRIP || drawMode == GL11.GL_TRIANGLE_FAN || drawMode == GL11.GL_LINE_STRIP ||
drawMode == GL11.GL_LINE_LOOP || drawMode == GL11.GL_QUAD_STRIP || drawMode == GL11.GL_POLYGON)
break;
}
TessellatorStreamingDrawer.drawPackedBatch(
batchTessellator, ranges, i, subEnd, totalBytes, totalVertices, drawMode, flags);
TessellatorStreamingDrawer.drawPackedBatch(batchTessellator, ranges, i, subEnd, totalBytes, totalVertices, drawMode, flags);
i = subEnd;
}
@@ -1,34 +1,33 @@
package com.gtnewhorizons.angelica.compat.bettercrashes;
import com.gtnewhorizons.angelica.AngelicaMod;
import com.gtnewhorizons.angelica.glsm.GLStateManager;
import com.gtnewhorizons.angelica.mixins.interfaces.IRenderGlobalExt;
import cpw.mods.fml.common.Optional;
import net.minecraft.client.Minecraft;
import vfyjxf.bettercrashes.utils.StateManager;
import static com.gtnewhorizons.angelica.loading.AngelicaTweaker.LOGGER;
@Optional.Interface(modid = "angelica", iface = "vfyjxf.bettercrashes.utils.StateManager.IResettable")
public class BetterCrashesCompat implements StateManager.IResettable {
private static BetterCrashesCompat INSTANCE;
public BetterCrashesCompat() {
AngelicaMod.LOGGER.info("BetterCrashesCompat initialized");
this.register();
}
public static void init() {
if (INSTANCE == null) {
INSTANCE = new BetterCrashesCompat();
}
}
public BetterCrashesCompat() {
LOGGER.info("BetterCrashesCompat initialized");
this.register();
}
@Override
public void resetState() {
LOGGER.info("Reloading SodiumRenderer");
AngelicaMod.LOGGER.info("Reloading SodiumRenderer");
((IRenderGlobalExt) Minecraft.getMinecraft().renderGlobal).angelica$reload();
LOGGER.info("Resetting GLStateManager");
AngelicaMod.LOGGER.info("Resetting GLStateManager");
GLStateManager.reset();
}
}
@@ -224,6 +224,13 @@ public class AngelicaConfig {
})
public static String[] blockCrackFixRenderPassWhitelist__;
@Config.Comment({"List of sprites which should always be treated as translucent.",
"Sprites added to this list will always be considered translucent,",
"",
"Requires texture reload (F3+T) to take effect."})
@Config.DefaultStringList({"jewelrycraft2:blockCrystal"})
public static String[] alwaysTranslucentSprites;
@Config.Comment("Register HardcodedCustomUniforms in Iris Shaders. May help with compatibility in certain shader packs")
@Config.DefaultBoolean(false)
public static boolean enableHardcodedCustomUniforms;
@@ -232,6 +239,31 @@ public class AngelicaConfig {
@Config.DefaultBoolean(true)
public static boolean defineIsIris;
@Config.Comment("ASM transformer exclusion narrowing for mod compatibility. Disable per-mod if narrowing causes class loading issues.")
public static TransformerCompat transformerCompat = new TransformerCompat();
public static class TransformerCompat {
@Config.Comment("Narrow DragonAPI transformer exclusions to allow GL redirection")
@Config.DefaultBoolean(true)
@Config.RequiresMcRestart
public boolean narrowDragonAPI;
@Config.Comment("Narrow Xaeros Minimap/Worldmap transformer exclusions to allow GL redirection")
@Config.DefaultBoolean(true)
@Config.RequiresMcRestart
public boolean narrowXaeros;
@Config.Comment("Narrow AdvancedLightsabers transformer exclusions to allow GL redirection")
@Config.DefaultBoolean(true)
@Config.RequiresMcRestart
public boolean narrowAdvancedLightsabers;
@Config.Comment("Narrow Alfheim transformer exclusions to allow GL redirection")
@Config.DefaultBoolean(true)
@Config.RequiresMcRestart
public boolean narrowAlfheim;
}
@Config.Comment("Renders chunks before neighbors are ready. Improves loading at render distance edges, useful for low render distance servers.")
@Config.DefaultBoolean(false)
public static boolean useVanillaChunkTracking;
@@ -25,6 +25,7 @@ import net.minecraft.client.renderer.EntityRenderer;
import net.minecraftforge.client.GuiIngameForge;
import net.minecraftforge.client.event.RenderGameOverlayEvent;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL13;
import thaumcraft.common.Thaumcraft;
import xaero.common.core.XaeroMinimapCore;
@@ -69,6 +70,12 @@ public class HUDCaching {
XaeroMinimapCore.beforeIngameGuiRender(partialTicks);
}
GLStateManager.disableLighting();
GLStateManager.glActiveTexture(GL13.GL_TEXTURE1);
GLStateManager.disableTexture();
GLStateManager.glActiveTexture(GL13.GL_TEXTURE0);
GLStateManager.enableTexture();
if (!AngelicaConfig.hudCachingActive || !GLStateManager.isFramebufferEnabled()) {
ingame.renderGameOverlay(partialTicks, hasScreen, mouseX, mouseY);
return;
@@ -14,6 +14,7 @@ import net.coderbot.iris.pipeline.DeferredWorldRenderingPipeline;
import net.coderbot.iris.pipeline.WorldRenderingPipeline;
import net.coderbot.iris.samplers.IrisSamplers;
import net.coderbot.iris.texture.pbr.PBRTextureManager;
import net.coderbot.iris.vertices.ImmediateState;
public class IrisGLSMBridge {
@@ -114,10 +115,10 @@ public class IrisGLSMBridge {
if (!drp.shouldOverrideShaders()) return;
if (drp.getActivePassProgramId() == -1) return;
if (DepthColorStorage.isOwnedProgram(event.newProgram)) {
if (!ImmediateState.isRenderingLevel || DepthColorStorage.isOwnedProgram(event.newProgram)) {
DepthColorStorage.unlockDepthColor();
} else {
DepthColorStorage.disableDepthColor();
drp.onModProgramOverride();
}
});
}
@@ -0,0 +1,226 @@
package com.gtnewhorizons.angelica.loading;
import com.gtnewhorizon.gtnhlib.config.ConfigException;
import com.gtnewhorizon.gtnhlib.config.ConfigurationManager;
import com.gtnewhorizon.gtnhmixins.IEarlyMixinLoader;
import com.gtnewhorizon.gtnhmixins.builders.IMixins;
import com.gtnewhorizon.gtnhmixins.builders.ITransformers;
import com.gtnewhorizons.angelica.config.AngelicaConfig;
import com.gtnewhorizons.angelica.config.CompatConfig;
import com.gtnewhorizons.angelica.config.FontConfig;
import com.gtnewhorizons.angelica.loading.fml.compat.CompatHandlers;
import com.gtnewhorizons.angelica.mixins.Mixins;
import com.gtnewhorizons.retrofuturabootstrap.SharedConfig;
import cpw.mods.fml.relauncher.FMLLaunchHandler;
import cpw.mods.fml.relauncher.IFMLLoadingPlugin;
import jss.notfine.asm.AsmTransformers;
import jss.notfine.asm.mappings.Namer;
import jss.notfine.config.MCPatcherForgeConfig;
import jss.notfine.config.NotFineConfig;
import net.minecraft.launchwrapper.Launch;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.core.LoggerContext;
import org.apache.logging.log4j.core.config.Configuration;
import org.apache.logging.log4j.core.config.LoggerConfig;
import org.spongepowered.asm.launch.GlobalProperties;
import org.spongepowered.asm.service.mojang.MixinServiceLaunchWrapper;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Set;
// this is not the real IFMLLoadingPlugin, if you put any annotations
// here it won't do anything, that's why we register transformer
// exclusions manually in the constructor
public final class AngelicaClientTweaker implements IFMLLoadingPlugin, IEarlyMixinLoader {
public static final Logger LOGGER = LogManager.getLogger("Angelica");
private static Boolean OBF_ENV;
private String[] transformerClasses;
public AngelicaClientTweaker() {
Launch.classLoader.addTransformerExclusion("jss.notfine.asm");
Launch.classLoader.addTransformerExclusion("com.gtnewhorizons.angelica.loading");
Launch.classLoader.addTransformerExclusion("com.gtnewhorizons.angelica.glsm.GLStateManager");
if (Launch.blackboard.getOrDefault("angelica.rfbPluginLoaded", Boolean.FALSE) == Boolean.TRUE) {
addLwjgl3ifyExclusions();
}
try {
// Angelica Config
ConfigurationManager.registerConfig(AngelicaConfig.class);
ConfigurationManager.registerConfig(CompatConfig.class);
ConfigurationManager.registerConfig(FontConfig.class);
MCPatcherForgeConfig.registerConfig();
final LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
final Configuration config = ctx.getConfiguration();
final LoggerConfig loggerConfig = config.getLoggerConfig(LogManager.ROOT_LOGGER_NAME);
if (AngelicaConfig.enableDebugLogging) {
loggerConfig.setLevel(Level.DEBUG);
}
ctx.updateLoggers();
// Debug features
AngelicaConfig.enableTestBlocks = Boolean.getBoolean("angelica.enableTestBlocks");
} catch (ConfigException e) {
throw new RuntimeException(e);
}
verifyDependencies();
// Register a scoped redirector early so classes prematurely loaded by other coremods during discovery/injectData
// (e.g. Mycelium using HookLoader.class.getName()) still get GL calls redirected to GLSM. Only targets specific mod
// packages to avoid interfering with mixin delegation on game classes. AngelicaLateTweaker removes this registration once
// mixins are setup.
if (FMLLaunchHandler.side().isClient()) {
final boolean rfbLoaded = Launch.blackboard.getOrDefault("angelica.rfbPluginLoaded", Boolean.FALSE) == Boolean.TRUE;
if (!rfbLoaded) {
Launch.classLoader.registerTransformer("com.gtnewhorizons.angelica.loading.fml.transformers.EarlyRedirectorTransformer");
}
}
}
private static void addLwjgl3ifyExclusions() {
final var handle = SharedConfig.getRfbTransformers().stream()
.filter(transformer -> transformer.id().equals("lwjgl3ify:redirect"))
.findFirst()
.orElse(null);
if (handle != null) {
handle.exclusions().add("org.embeddedt.embeddium");
handle.exclusions().add("org.taumc.celeritas");
handle.exclusions().add("com.mitchej123.lwjgl.lwjgl3");
handle.exclusions().add("com.mitchej123.glsm");
handle.exclusions().add("com.gtnewhorizons.angelica.lwjgl3");
handle.exclusions().add("com.gtnewhorizons.angelica.vulkan");
}
}
private static void verifyDependencies() {
// Check for fastutil (bundled with GTNHLib since 0.2.1)
if (AngelicaTweaker.class.getResource("/it/unimi/dsi/fastutil/ints/Int2ObjectMap.class") == null) {
throw new RuntimeException("Missing dependency: Angelica requires GTNHLib! Download: https://modrinth.com/mod/gtnhlib");
}
// Check for PrimitiveExtractor/cel.model classes (added in GTNHLib 0.8.21)
if (AngelicaTweaker.class.getResource("/com/gtnewhorizon/gtnhlib/client/renderer/PrimitiveExtractor.class") == null) {
throw new RuntimeException("GTNHLib is outdated: Angelica requires GTNHLib 0.8.21 or newer! Download: https://modrinth.com/mod/gtnhlib");
}
// Check for jvmdowngrader stubs (bundled with GTNHLib since 0.9.0)
if (AngelicaTweaker.class.getResource("/xyz/wagyourtail/jvmdg/exc/MissingStubError.class") == null) {
throw new RuntimeException("GTNHLib is outdated: Angelica requires GTNHLib 0.9.0 or newer! Download: https://modrinth.com/mod/gtnhlib");
}
}
@Override
public String[] getASMTransformerClass() {
if (transformerClasses == null) {
final List<String> transformers = new ArrayList<>();
transformers.addAll(CompatHandlers.getTransformers());
// Add NotFine transformers
final List<String> notFineTransformers = Arrays.asList(ITransformers.getTransformers(AsmTransformers.class));
if (!notFineTransformers.isEmpty()) Namer.initNames();
transformers.addAll(notFineTransformers);
transformerClasses = transformers.toArray(new String[0]);
}
return transformerClasses;
}
@Override
public String getModContainerClass() {
return null;
}
@Override
public String getSetupClass() {
return null;
}
@Override
public void injectData(Map<String, Object> data) {
OBF_ENV = (Boolean) data.get("runtimeDeobfuscationEnabled");
// Directly add this to the MixinServiceLaunchWrapper tweaker's list of Tweak Classes
final List<String> tweaks = GlobalProperties.get(MixinServiceLaunchWrapper.BLACKBOARD_KEY_TWEAKCLASSES);
if (tweaks != null) {
// Bridge transformer compat config to blackboard for AngelicaLateTweaker
narrowTransformerConfig("DragonAPI", AngelicaConfig.transformerCompat.narrowDragonAPI);
narrowTransformerConfig("Xaeros", AngelicaConfig.transformerCompat.narrowXaeros);
narrowTransformerConfig("AdvancedLightsabers", AngelicaConfig.transformerCompat.narrowAdvancedLightsabers);
narrowTransformerConfig("Alfheim", AngelicaConfig.transformerCompat.narrowAlfheim);
tweaks.add("com.gtnewhorizons.angelica.loading.fml.tweakers.IncompatibleModsDisablerTweaker");
if (AngelicaConfig.enableHudCaching) {
tweaks.add("com.gtnewhorizons.angelica.loading.fml.tweakers.XaerosTransformerDisablerTweaker");
}
if (FMLLaunchHandler.side().isClient()) {
// We register ITweakers that will run last in order to register
// specific IClassTransformers that will run last in the transformer chain.
// If we were to register them normally in getASMTransformerClass(),
// they would be sorted at index 0 which we do not want.
final boolean rfbLoaded = Launch.blackboard.getOrDefault("angelica.rfbPluginLoaded", Boolean.FALSE) == Boolean.TRUE;
if (!rfbLoaded) {
tweaks.add("com.gtnewhorizons.angelica.loading.fml.tweakers.AngelicaLateTweaker");
if (AngelicaConfig.enableCeleritas) {
tweaks.add("com.gtnewhorizons.angelica.loading.fml.tweakers.CeleritasLateTweaker");
}
}
}
}
}
/** Publish a transformer-narrowing toggle to the blackboard; read by AngelicaLateTweaker.narrowEnabled(). */
private static void narrowTransformerConfig(String mod, boolean enabled) {
Launch.blackboard.put("angelica.narrow." + mod, enabled);
}
@Override
public String getAccessTransformerClass() {
return null;
}
@Override
public String getMixinConfig() {
final int v = Runtime.version().feature();
if (v >= 21) return "mixins.angelica.early.j21.json";
if (v >= 17) return "mixins.angelica.early.j17.json";
return "mixins.angelica.early.json";
}
@Override
public List<String> getMixins(Set<String> loadedCoreMods) {
NotFineConfig.loadSettings();
//This may be possible to handle differently or fix.
if (loadedCoreMods.contains("cofh.asm.LoadingPlugin")) {
MCPatcherForgeConfig.ExtendedHD.hdFont = false;
}
return IMixins.getEarlyMixins(Mixins.class, loadedCoreMods);
}
/**
* Returns true if we are in an obfuscated environment, returns false in dev environment.
*/
public static boolean isObfEnv() {
if (OBF_ENV == null) {
throw new IllegalStateException("Obfuscation state has been accessed too early!");
}
return OBF_ENV;
}
/**
* Returns the appropriate name according to current environment's obfuscation
*/
public static String obf(String deobf, String obf) {
if (OBF_ENV == null) {
throw new IllegalStateException("Obfuscation state has been accessed too early!");
}
if (OBF_ENV) {
return obf;
}
return deobf;
}
}
@@ -1,34 +1,12 @@
package com.gtnewhorizons.angelica.loading;
import com.gtnewhorizon.gtnhlib.config.ConfigException;
import com.gtnewhorizon.gtnhlib.config.ConfigurationManager;
import com.gtnewhorizon.gtnhmixins.IEarlyMixinLoader;
import com.gtnewhorizon.gtnhmixins.builders.IMixins;
import com.gtnewhorizon.gtnhmixins.builders.ITransformers;
import com.gtnewhorizons.angelica.config.AngelicaConfig;
import com.gtnewhorizons.angelica.config.CompatConfig;
import com.gtnewhorizons.angelica.config.FontConfig;
import com.gtnewhorizons.angelica.mixins.Mixins;
import com.gtnewhorizons.angelica.loading.fml.compat.CompatHandlers;
import cpw.mods.fml.relauncher.FMLLaunchHandler;
import cpw.mods.fml.relauncher.IFMLLoadingPlugin;
import jss.notfine.asm.AsmTransformers;
import jss.notfine.asm.mappings.Namer;
import jss.notfine.config.MCPatcherForgeConfig;
import jss.notfine.config.NotFineConfig;
import com.gtnewhorizons.retrofuturabootstrap.SharedConfig;
import net.minecraft.launchwrapper.Launch;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.core.LoggerContext;
import org.apache.logging.log4j.core.config.Configuration;
import org.apache.logging.log4j.core.config.LoggerConfig;
import org.spongepowered.asm.launch.GlobalProperties;
import org.spongepowered.asm.service.mojang.MixinServiceLaunchWrapper;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -41,184 +19,76 @@ import java.util.Set;
// They will instead use default index 0 which means they will see
// obfuscated mappings and not SRG mappings when running outside of dev env.
// ===============================================
//@IFMLLoadingPlugin.SortingIndex(Integer.MAX_VALUE - 5)
@IFMLLoadingPlugin.MCVersion("1.7.10")
@IFMLLoadingPlugin.TransformerExclusions({
"jss.notfine.asm",
"com.gtnewhorizons.angelica.loading",
"com.gtnewhorizons.angelica.glsm.GLStateManager"
})
public class AngelicaTweaker implements IFMLLoadingPlugin, IEarlyMixinLoader {
private static Boolean OBF_ENV;
public static final Logger LOGGER = LogManager.getLogger("Angelica");
private String[] transformerClasses;
private final IFMLLoadingPlugin loadingPlugin;
private final IEarlyMixinLoader mixinLoader;
public AngelicaTweaker() {
if (Launch.blackboard.getOrDefault("angelica.rfbPluginLoaded", Boolean.FALSE) == Boolean.TRUE) {
addLwjgl3ifyExclusions();
}
try {
// Angelica Config
ConfigurationManager.registerConfig(AngelicaConfig.class);
ConfigurationManager.registerConfig(CompatConfig.class);
ConfigurationManager.registerConfig(FontConfig.class);
MCPatcherForgeConfig.registerConfig();
final LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
final Configuration config = ctx.getConfiguration();
final LoggerConfig loggerConfig = config.getLoggerConfig(LogManager.ROOT_LOGGER_NAME);
if (AngelicaConfig.enableDebugLogging) {
loggerConfig.setLevel(Level.DEBUG);
}
ctx.updateLoggers();
// Debug features
AngelicaConfig.enableTestBlocks = Boolean.getBoolean("angelica.enableTestBlocks");
} catch (ConfigException e) {
throw new RuntimeException(e);
}
verifyDependencies();
// Register a scoped redirector early so classes prematurely loaded by other coremods during discovery/injectData
// (e.g. Mycelium using HookLoader.class.getName()) still get GL calls redirected to GLSM. Only targets specific mod
// packages to avoid interfering with mixin delegation on game classes. AngelicaLateTweaker removes this registration once
// mixins are setup.
if (FMLLaunchHandler.side().isClient()) {
final boolean rfbLoaded = Launch.blackboard.getOrDefault("angelica.rfbPluginLoaded", Boolean.FALSE) == Boolean.TRUE;
if (!rfbLoaded) {
Launch.classLoader.registerTransformer("com.gtnewhorizons.angelica.loading.fml.transformers.EarlyRedirectorTransformer");
}
}
}
private static void verifyDependencies() {
// Check for fastutil (bundled with GTNHLib since 0.2.1)
if (AngelicaTweaker.class.getResource("/it/unimi/dsi/fastutil/ints/Int2ObjectMap.class") == null) {
throw new RuntimeException("Missing dependency: Angelica requires GTNHLib! Download: https://modrinth.com/mod/gtnhlib");
}
// Check for PrimitiveExtractor/cel.model classes (added in GTNHLib 0.8.21)
if (AngelicaTweaker.class.getResource("/com/gtnewhorizon/gtnhlib/client/renderer/PrimitiveExtractor.class") == null) {
throw new RuntimeException("GTNHLib is outdated: Angelica requires GTNHLib 0.8.21 or newer! Download: https://modrinth.com/mod/gtnhlib");
}
// Check for jvmdowngrader stubs (bundled with GTNHLib since 0.9.0)
if (AngelicaTweaker.class.getResource("/xyz/wagyourtail/jvmdg/exc/MissingStubError.class") == null) {
throw new RuntimeException("GTNHLib is outdated: Angelica requires GTNHLib 0.9.0 or newer! Download: https://modrinth.com/mod/gtnhlib");
final AngelicaClientTweaker clientTweaker = new AngelicaClientTweaker();
loadingPlugin = clientTweaker;
mixinLoader = clientTweaker;
} else {
loadingPlugin = null;
mixinLoader = null;
LogManager.getLogger("Angelica").info("Trying to get more FPS on your server ? :kekw:");
}
}
@Override
public String[] getASMTransformerClass() {
if (transformerClasses == null) {
final List<String> transformers = new ArrayList<>();
transformers.addAll(CompatHandlers.getTransformers());
// Add NotFine transformers
final List<String> notFineTransformers = Arrays.asList(ITransformers.getTransformers(AsmTransformers.class));
if (!notFineTransformers.isEmpty()) Namer.initNames();
transformers.addAll(notFineTransformers);
transformerClasses = transformers.toArray(new String[0]);
if (this.loadingPlugin != null) {
return this.loadingPlugin.getASMTransformerClass();
}
return transformerClasses;
return null;
}
@Override
public String getModContainerClass() {
if (this.loadingPlugin != null) {
return this.loadingPlugin.getModContainerClass();
}
return null;
}
@Override
public String getSetupClass() {
if (this.loadingPlugin != null) {
return this.loadingPlugin.getSetupClass();
}
return null;
}
@Override
public void injectData(Map<String, Object> data) {
OBF_ENV = (Boolean) data.get("runtimeDeobfuscationEnabled");
// Directly add this to the MixinServiceLaunchWrapper tweaker's list of Tweak Classes
final List<String> tweaks = GlobalProperties.get(MixinServiceLaunchWrapper.BLACKBOARD_KEY_TWEAKCLASSES);
if (tweaks != null) {
tweaks.add("com.gtnewhorizons.angelica.loading.fml.tweakers.IncompatibleModsDisablerTweaker");
if (AngelicaConfig.enableHudCaching) {
tweaks.add("com.gtnewhorizons.angelica.loading.fml.tweakers.XaerosTransformerDisablerTweaker");
}
if (FMLLaunchHandler.side().isClient()) {
// We register ITweakers that will run last in order to register
// specific IClassTransformers that will run last in the transformer chain.
// If we were to register them normally in getASMTransformerClass(),
// they would be sorted at index 0 which we do not want.
final boolean rfbLoaded = Launch.blackboard.getOrDefault("angelica.rfbPluginLoaded", Boolean.FALSE) == Boolean.TRUE;
if (!rfbLoaded) {
tweaks.add("com.gtnewhorizons.angelica.loading.fml.tweakers.AngelicaLateTweaker");
if (AngelicaConfig.enableCeleritas) {
tweaks.add("com.gtnewhorizons.angelica.loading.fml.tweakers.CeleritasLateTweaker");
}
}
}
if (this.loadingPlugin != null) {
this.loadingPlugin.injectData(data);
}
}
@Override
public String getAccessTransformerClass() {
if (this.loadingPlugin != null) {
return this.loadingPlugin.getAccessTransformerClass();
}
return null;
}
@Override
public String getMixinConfig() {
final int v = Runtime.version().feature();
if (v >= 21) return "mixins.angelica.early.j21.json";
if (v >= 17) return "mixins.angelica.early.j17.json";
return "mixins.angelica.early.json";
if (this.mixinLoader != null) {
return this.mixinLoader.getMixinConfig();
}
return "mixins.angelica.server.json";
}
@Override
public List<String> getMixins(Set<String> loadedCoreMods) {
NotFineConfig.loadSettings();
//This may be possible to handle differently or fix.
if (loadedCoreMods.contains("cofh.asm.LoadingPlugin")) {
MCPatcherForgeConfig.ExtendedHD.hdFont = false;
if (this.mixinLoader != null) {
return this.mixinLoader.getMixins(loadedCoreMods);
}
return IMixins.getEarlyMixins(Mixins.class, loadedCoreMods);
}
private static void addLwjgl3ifyExclusions() {
final var handle = SharedConfig.getRfbTransformers().stream()
.filter(transformer -> transformer.id().equals("lwjgl3ify:redirect"))
.findFirst()
.orElse(null);
if (handle != null) {
handle.exclusions().add("org.embeddedt.embeddium");
handle.exclusions().add("org.taumc.celeritas");
handle.exclusions().add("com.mitchej123.lwjgl.lwjgl3");
handle.exclusions().add("com.mitchej123.glsm");
handle.exclusions().add("com.gtnewhorizons.angelica.lwjgl3");
handle.exclusions().add("com.gtnewhorizons.angelica.vulkan");
}
}
/**
* Returns true if we are in an obfuscated environment, returns false in dev environment.
*/
public static boolean isObfEnv() {
if (OBF_ENV == null) {
throw new IllegalStateException("Obfuscation state has been accessed too early!");
}
return OBF_ENV;
}
/**
* Returns the appropriate name according to current environment's obfuscation
*/
public static String obf(String deobf, String obf) {
if (OBF_ENV == null) {
throw new IllegalStateException("Obfuscation state has been accessed too early!");
}
if (OBF_ENV) {
return obf;
}
return deobf;
return Collections.emptyList();
}
}
@@ -1,6 +1,6 @@
package com.gtnewhorizons.angelica.loading.fml.compat.transformers.generic;
import com.gtnewhorizons.angelica.loading.AngelicaTweaker;
import com.gtnewhorizons.angelica.loading.AngelicaClientTweaker;
import org.spongepowered.asm.lib.Opcodes;
import org.spongepowered.asm.lib.tree.AbstractInsnNode;
import org.spongepowered.asm.lib.tree.ClassNode;
@@ -62,7 +62,7 @@ public class FieldLevelTessellatorTransformer {
new FieldInsnNode(
Opcodes.GETSTATIC,
"net/minecraft/client/renderer/Tessellator",
AngelicaTweaker.obf("instance", "field_78398_a"),
AngelicaClientTweaker.obf("instance", "field_78398_a"),
"Lnet/minecraft/client/renderer/Tessellator;"));
list.add(new VarInsnNode(Opcodes.ASTORE, localIndex));
mn.instructions.insert(list);
@@ -1,6 +1,6 @@
package com.gtnewhorizons.angelica.loading.fml.compat.transformers.generic;
import com.gtnewhorizons.angelica.loading.AngelicaTweaker;
import com.gtnewhorizons.angelica.loading.AngelicaClientTweaker;
import org.spongepowered.asm.lib.Opcodes;
import org.spongepowered.asm.lib.tree.ClassNode;
import org.spongepowered.asm.lib.tree.InsnList;
@@ -29,7 +29,7 @@ public class HUDCachingEarlyReturnTransformer {
} else if (method.desc.endsWith("V")) {
list.add(new InsnNode(Opcodes.RETURN));
} else {
AngelicaTweaker.LOGGER.warn(
AngelicaClientTweaker.LOGGER.warn(
"HUDCaching Conditional Return - Unknown return type: {}#{}:{}", cn.name, method.name, method.desc
);
return;
@@ -1,6 +1,6 @@
package com.gtnewhorizons.angelica.loading.fml.compat.transformers.generic;
import com.gtnewhorizons.angelica.loading.AngelicaTweaker;
import com.gtnewhorizons.angelica.loading.AngelicaClientTweaker;
import org.spongepowered.asm.lib.Opcodes;
import org.spongepowered.asm.lib.tree.AbstractInsnNode;
import org.spongepowered.asm.lib.tree.ClassNode;
@@ -59,7 +59,7 @@ public class TileEntityNullGuardTransformer {
AbstractInsnNode in = mn.instructions.get(i);
if (in instanceof MethodInsnNode min) {
if (min.getOpcode() == Opcodes.INVOKEINTERFACE
&& min.name.equals(AngelicaTweaker.obf("getTileEntity", "func_147438_o"))
&& min.name.equals(AngelicaClientTweaker.obf("getTileEntity", "func_147438_o"))
&& min.owner.equals("net/minecraft/world/IBlockAccess")) {
AbstractInsnNode castNodeAbstract = min.getNext();
if (castNodeAbstract instanceof TypeInsnNode castNodeType) {
@@ -77,7 +77,7 @@ public class TileEntityNullGuardTransformer {
} else if (mn.desc.endsWith("V")) {
list.add(new InsnNode(Opcodes.RETURN));
} else {
AngelicaTweaker.LOGGER.warn("TileEntityNullGuard - Unknown Return Type: {}:{}", mn.name, mn.desc);
AngelicaClientTweaker.LOGGER.warn("TileEntityNullGuard - Unknown Return Type: {}:{}", mn.name, mn.desc);
return;
}
list.add(exit);
@@ -1,6 +1,6 @@
package com.gtnewhorizons.angelica.loading.fml.compat.transformers.specific;
import com.gtnewhorizons.angelica.loading.AngelicaTweaker;
import com.gtnewhorizons.angelica.loading.AngelicaClientTweaker;
import com.gtnewhorizons.angelica.loading.shared.AngelicaClassDump;
import net.minecraft.launchwrapper.IClassTransformer;
import org.spongepowered.asm.lib.ClassReader;
@@ -60,7 +60,7 @@ public class ImmersiveEngineeringTransformer implements IClassTransformer {
MixinClassWriter cw = new MixinClassWriter(MixinClassWriter.COMPUTE_FRAMES);
cn.accept(cw);
final byte[] bytes = cw.toByteArray();
AngelicaTweaker.LOGGER.info("[AngelicaCompat]Extra Transformers: Applied ImmersiveEngineeringTransformer");
AngelicaClientTweaker.LOGGER.info("[AngelicaCompat]Extra Transformers: Applied ImmersiveEngineeringTransformer");
AngelicaClassDump.dumpClass(transformedName, basicClass, bytes, this);
return bytes;
}
@@ -1,7 +1,7 @@
package com.gtnewhorizons.angelica.loading.fml.compat.transformers.specific;
import com.google.common.collect.ImmutableList;
import com.gtnewhorizons.angelica.loading.AngelicaTweaker;
import com.gtnewhorizons.angelica.loading.AngelicaClientTweaker;
import com.gtnewhorizons.angelica.loading.shared.AngelicaClassDump;
import net.minecraft.launchwrapper.IClassTransformer;
import org.spongepowered.asm.lib.ClassReader;
@@ -47,7 +47,7 @@ public class StacksOnStacksTransformer implements IClassTransformer {
ClassWriter cw = new ClassWriter(0);
cn.accept(cw);
final byte[] bytes = cw.toByteArray();
AngelicaTweaker.LOGGER.info("[AngelicaCompat]Extra Transformers: Applied StacksOnStacksTransformer");
AngelicaClientTweaker.LOGGER.info("[AngelicaCompat]Extra Transformers: Applied StacksOnStacksTransformer");
AngelicaClassDump.dumpClass(transformedName, basicClass, bytes, this);
return bytes;
}
@@ -1,6 +1,6 @@
package com.gtnewhorizons.angelica.loading.fml.transformers;
import com.gtnewhorizons.angelica.loading.AngelicaTweaker;
import com.gtnewhorizons.angelica.loading.AngelicaClientTweaker;
import com.gtnewhorizons.angelica.loading.shared.AngelicaClassDump;
import com.gtnewhorizons.angelica.loading.shared.transformers.CeleritasBlockTransform;
import net.minecraft.launchwrapper.IClassTransformer;
@@ -14,7 +14,7 @@ public class CeleritasBlockTransformer implements IClassTransformer {
private final String[] exclusions;
public CeleritasBlockTransformer() {
this.inner = new CeleritasBlockTransform(AngelicaTweaker.isObfEnv());
this.inner = new CeleritasBlockTransform(AngelicaClientTweaker.isObfEnv());
this.exclusions = inner.getTransformerExclusions();
this.inner.setCeleritasSetting();
}
@@ -37,10 +37,8 @@ public class AngelicaLateTweaker implements ITweaker {
exceptionsField.setAccessible(true);
final Set<String> exceptions = (Set<String>) exceptionsField.get(classLoader);
if (exceptions.remove("Reika.DragonAPI.ASM")) {
// Don't read ASMCallsClient and Patchers/Fixes/WorldRenderAlpha. The rest are fair game.
// Re-add the other non utility classes
if (narrowEnabled("DragonAPI") && exceptions.remove("Reika.DragonAPI.ASM")) {
// Re-add non-GL classes; ASMCallsClient and utility classes with GL calls are left exposed
exceptions.add("Reika.DragonAPI.ASM.Patchers");
exceptions.add("Reika.DragonAPI.ASM.Profiling");
exceptions.add("Reika.DragonAPI.ASM.APIStripper");
@@ -52,22 +50,60 @@ public class AngelicaLateTweaker implements ITweaker {
exceptions.add("Reika.DragonAPI.ASM.InterfaceInjector");
exceptions.add("Reika.DragonAPI.ASM.SpecialBiomePlacement");
exceptions.add("Reika.DragonAPI.ASM.StructureLootHooks");
FMLRelaunchLog.info("[Angelica] Narrowed Reika.DragonAPI.ASM transformer exclusion to allow GL redirection of utility classes");
FMLRelaunchLog.info("[Angelica] Narrowed Reika.DragonAPI.ASM transformer exclusion to allow GL redirection");
}
if (exceptions.remove("xaero.common.core")) {
exceptions.add("xaero.common.core.transformer");
FMLRelaunchLog.info("[Angelica] Narrowed xaero.common.core transformer exclusion to allow GL redirection");
if (narrowEnabled("Xaeros")) {
if (exceptions.remove("xaero.common.core")) {
exceptions.add("xaero.common.core.transformer");
FMLRelaunchLog.info("[Angelica] Narrowed xaero.common.core transformer exclusion to allow GL redirection");
}
if (exceptions.remove("xaero.map.core")) {
exceptions.add("xaero.map.core.transformer");
FMLRelaunchLog.info("[Angelica] Narrowed xaero.map.core transformer exclusion to allow GL redirection");
}
}
if (exceptions.remove("xaero.map.core")) {
exceptions.add("xaero.map.core.transformer");
FMLRelaunchLog.info("[Angelica] Narrowed xaero.map.core transformer exclusion to allow GL redirection");
if (narrowEnabled("AdvancedLightsabers") && exceptions.remove("com.fiskmods.lightsabers.asm")) {
exceptions.add("com.fiskmods.lightsabers.asm.ALLoadingPlugin");
exceptions.add("com.fiskmods.lightsabers.asm.ASMHooks");
exceptions.add("com.fiskmods.lightsabers.asm.transformers");
FMLRelaunchLog.info("[Angelica] Narrowed com.fiskmods.lightsabers.asm transformer exclusion to allow GL redirection");
}
if (narrowEnabled("Alfheim") && exceptions.remove("alfheim.common.core.asm.hook")) {
exceptions.add("alfheim.common.core.asm.hook.AlfheimFieldHookHandler");
exceptions.add("alfheim.common.core.asm.hook.AlfheimHPHooks");
exceptions.add("alfheim.common.core.asm.hook.Botania18AndUpBackport");
exceptions.add("alfheim.common.core.asm.hook.ElementalDamageAdapter");
exceptions.add("alfheim.common.core.asm.hook.integration");
exceptions.add("alfheim.common.core.asm.hook.extender.FurnaceExtender");
exceptions.add("alfheim.common.core.asm.hook.extender.ItemAuraRingExtender");
exceptions.add("alfheim.common.core.asm.hook.extender.ItemLensExtender");
exceptions.add("alfheim.common.core.asm.hook.extender.ItemTwigWandExtender");
exceptions.add("alfheim.common.core.asm.hook.extender.LightRelayExtender");
exceptions.add("alfheim.common.core.asm.hook.extender.PureDaisyExtender");
exceptions.add("alfheim.common.core.asm.hook.extender.QuartzExtender");
exceptions.add("alfheim.common.core.asm.hook.extender.RelicHooks");
exceptions.add("alfheim.common.core.asm.hook.extender.SparkExtender");
exceptions.add("alfheim.common.core.asm.hook.fixes.BotaniaGlowingRenderFixes");
exceptions.add("alfheim.common.core.asm.hook.fixes.CorporeaInputFix");
exceptions.add("alfheim.common.core.asm.hook.fixes.GodAttributesHooks");
exceptions.add("alfheim.common.core.asm.hook.fixes.RecipeAncientWillsFix");
FMLRelaunchLog.info("[Angelica] Narrowed alfheim.common.core.asm.hook transformer exclusion to allow GL redirection");
}
} catch (Exception e) {
FMLRelaunchLog.warning("[Angelica] Failed to narrow transformer exclusions: %s", e.getMessage());
}
}
private static boolean narrowEnabled(String mod) {
return !Boolean.FALSE.equals(Launch.blackboard.get("angelica.narrow." + mod));
}
@Override
public String getLaunchTarget() {
return null;
@@ -36,6 +36,7 @@ public enum Mixins implements IMixins {
, "angelica.MixinMinecraft"
, "angelica.MixinMinecraft_FrameHook"
, "angelica.MixinMinecraftServer"
, "angelica.bugfixes.MixinItemRenderer_EdgeDepth"
, "angelica.bugfixes.MixinRenderGlobal_DestroyBlock"
, "angelica.bugfixes.MixinRendererLivingEntity_EyeDepth"
, "angelica.debug.MixinMinecraft_FPSCap"
@@ -4,20 +4,21 @@ import com.google.common.base.Objects;
import com.gtnewhorizon.gtnhlib.client.model.loading.ModelRegistry;
import com.gtnewhorizon.gtnhlib.client.renderer.vao.VAOManager;
import com.gtnewhorizons.angelica.commands.AngelicaCommand;
import com.gtnewhorizons.angelica.common.BlockError;
import com.gtnewhorizons.angelica.compat.ModStatus;
import com.gtnewhorizons.angelica.compat.bettercrashes.BetterCrashesCompat;
import com.gtnewhorizons.angelica.config.AngelicaConfig;
import com.gtnewhorizons.angelica.config.CompatConfig;
import com.gtnewhorizons.angelica.config.ConfigMigrator;
import com.gtnewhorizons.angelica.debug.F3Direction;
import com.gtnewhorizons.angelica.debug.FrametimeGraph;
import com.gtnewhorizons.angelica.debug.TPSGraph;
import com.gtnewhorizons.angelica.dynamiclights.DynamicLights;
import com.gtnewhorizons.angelica.dynamiclights.config.EntityLightConfig;
import com.gtnewhorizons.angelica.glsm.GLStateManager;
import com.gtnewhorizons.angelica.client.debug.OpenGLDebugging;
import com.gtnewhorizons.angelica.hudcaching.HUDCaching;
import com.gtnewhorizons.angelica.iris.IrisGLSMBridge;
import com.gtnewhorizons.angelica.loading.AngelicaTweaker;
import com.gtnewhorizons.angelica.loading.AngelicaClientTweaker;
import com.gtnewhorizons.angelica.mixins.interfaces.IGameSettingsExt;
import com.gtnewhorizons.angelica.render.CloudRenderer;
import com.gtnewhorizons.angelica.rendering.AngelicaBlockSafetyRegistry;
@@ -26,8 +27,9 @@ import com.gtnewhorizons.angelica.rendering.celeritas.CeleritasSetup;
import com.gtnewhorizons.angelica.rendering.celeritas.threading.ChunkTaskRegistry;
import com.gtnewhorizons.angelica.rendering.celeritas.threading.DefaultChunkTaskProvider;
import com.gtnewhorizons.angelica.rendering.celeritas.threading.ThreadedChunkTaskProvider;
import com.gtnewhorizons.angelica.utils.AnimationMode;
import com.gtnewhorizons.angelica.utils.ManagedEnum;
import com.gtnewhorizons.angelica.zoom.Zoom;
import cpw.mods.fml.client.registry.ClientRegistry;
import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.common.event.FMLInitializationEvent;
import cpw.mods.fml.common.event.FMLPostInitializationEvent;
@@ -41,20 +43,16 @@ import jss.notfine.core.Settings;
import jss.notfine.gui.GuiCustomMenu;
import jss.notfine.gui.NotFineGameOptionPages;
import me.flashyreese.mods.reeses_sodium_options.client.gui.ReeseSodiumVideoOptionsScreen;
import me.jellysquid.mods.sodium.client.gui.SodiumGameOptions;
import me.jellysquid.mods.sodium.client.gui.SodiumOptionsGUI;
import net.coderbot.iris.Iris;
import net.coderbot.iris.client.IrisDebugScreenHandler;
import net.minecraft.block.Block;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.gui.Gui;
import net.minecraft.client.gui.GuiMainMenu;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.client.gui.GuiVideoSettings;
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;
import net.minecraft.util.MathHelper;
@@ -69,29 +67,40 @@ import net.minecraftforge.client.event.GuiScreenEvent;
import net.minecraftforge.client.event.RenderGameOverlayEvent;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.event.world.WorldEvent;
import org.lwjgl.input.Keyboard;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.lang.management.ManagementFactory;
import java.util.Locale;
import java.util.concurrent.ConcurrentHashMap;
import static com.gtnewhorizons.angelica.AngelicaMod.MOD_ID;
import static com.gtnewhorizons.angelica.loading.AngelicaTweaker.LOGGER;
public class ClientProxy extends CommonProxy {
public final class ClientProxy extends CommonProxy {
final Minecraft mc = Minecraft.getMinecraft();
final FrametimeGraph frametimeGraph = new FrametimeGraph();
final TPSGraph tpsGraph = new TPSGraph();
public static BlockError blockError;
public static final ManagedEnum<AnimationMode> animationsMode = new ManagedEnum<>(AnimationMode.VISIBLE_ONLY);
private static final Logger LOGGER = LogManager.getLogger("Angelica");
private static SodiumGameOptions CONFIG;
private final Minecraft mc = Minecraft.getMinecraft();
private final FrametimeGraph frametimeGraph = new FrametimeGraph();
private final TPSGraph tpsGraph = new TPSGraph();
public static SodiumGameOptions options() {
if (CONFIG == null) {
CONFIG = SodiumGameOptions.load(ConfigMigrator.handleConfigMigration("angelica-options.json"));
}
return CONFIG;
}
@Override
public void preInit(FMLPreInitializationEvent event) {
ModStatus.preInit();
super.preInit(event);
FMLCommonHandler.instance().bus().register(this);
MinecraftForge.EVENT_BUS.register(this);
ModelRegistry.registerModid(MOD_ID);
blockError = new BlockError();
}
@SubscribeEvent
@@ -114,8 +123,6 @@ public class ClientProxy extends CommonProxy {
}
}
private static KeyBinding glsmKeyBinding;
@Override
public void init(FMLInitializationEvent event) {
super.init(event);
@@ -144,9 +151,6 @@ public class ClientProxy extends CommonProxy {
FMLCommonHandler.instance().bus().register(this);
MinecraftForge.EVENT_BUS.register(this);
glsmKeyBinding = new KeyBinding("Print GLSM Debug", Keyboard.KEY_NONE, "Angelica");
ClientRegistry.registerKeyBinding(glsmKeyBinding);
if (ModStatus.isBetterCrashesLoaded) {
BetterCrashesCompat.init();
}
@@ -158,23 +162,11 @@ public class ClientProxy extends CommonProxy {
}
// Register debug commands in dev environment only
if (!AngelicaTweaker.isObfEnv()) {
if (!AngelicaClientTweaker.isObfEnv()) {
ClientCommandHandler.instance.registerCommand(new AngelicaCommand());
}
}
private boolean wasGLSMKeyPressed;
@SubscribeEvent
public void onKeypress(TickEvent.ClientTickEvent event) {
if (event.phase != TickEvent.Phase.END) return;
final boolean isPressed = glsmKeyBinding.getKeyCode() != 0 && GameSettings.isKeyDown(glsmKeyBinding);
if (isPressed && !wasGLSMKeyPressed) {
OpenGLDebugging.checkGLSM();
}
wasGLSMKeyPressed = isPressed;
}
@Override
public void postInit(FMLPostInitializationEvent event) {
@@ -10,8 +10,7 @@ import cpw.mods.fml.common.registry.GameRegistry;
public class CommonProxy {
public void preInit(FMLPreInitializationEvent event) {
if (AngelicaConfig.enableTestBlocks){
if (AngelicaConfig.enableTestBlocks) {
GameRegistry.registerBlock(new BlockTest(), "test_block");
}
}
@@ -1,11 +1,11 @@
package com.gtnewhorizons.angelica.rendering.celeritas;
import com.gtnewhorizons.angelica.AngelicaMod;
import com.gtnewhorizons.angelica.api.ExtQuadLightData;
import com.gtnewhorizons.angelica.api.TintComputer;
import com.gtnewhorizons.angelica.api.TintRegistry;
import com.gtnewhorizons.angelica.dynamiclights.DynamicLights;
import com.gtnewhorizons.angelica.dynamiclights.IDynamicLightSource;
import com.gtnewhorizons.angelica.proxy.ClientProxy;
import com.gtnewhorizons.angelica.rendering.StateAwareTessellator;
import com.gtnewhorizons.angelica.rendering.celeritas.iris.BlockRenderContext;
import com.gtnewhorizons.angelica.rendering.celeritas.iris.IrisExtendedChunkVertexEncoder;
@@ -99,7 +99,7 @@ public class AngelicaChunkBuildContext extends ChunkBuildContext {
private Material selectMaterial(Material material, TextureAtlasSprite sprite, boolean isShaderPackOverride) {
// Don't apply transparency-based optimization when shader pack explicitly overrides the material
if (!AngelicaMod.options().performance.useRenderPassOptimization || isShaderPackOverride) {
if (!ClientProxy.options().performance.useRenderPassOptimization || isShaderPackOverride) {
return material;
}
if (sprite != null && sprite.getClass() == TextureAtlasSprite.class && !sprite.hasAnimationMetadata()) {
@@ -129,7 +129,7 @@ public class AngelicaChunkBuildContext extends ChunkBuildContext {
final boolean hasDynamicLights = chunkLightSources != null && !chunkLightSources.isEmpty();
final boolean separateAo = BlockRenderingSettings.INSTANCE.shouldUseSeparateAo();
final boolean celeritasSmoothLighting = AngelicaMod.options().quality.useCeleritasSmoothLighting;
final boolean celeritasSmoothLighting = ClientProxy.options().quality.useCeleritasSmoothLighting;
final boolean shaderActive = IrisApi.getInstance().isShaderPackInUse();
final boolean useAoCalculation = lightPipelineReady && (separateAo || celeritasSmoothLighting || shaderActive);
final boolean shouldApplyDiffuse = !BlockRenderingSettings.INSTANCE.shouldDisableDirectionalShading();
@@ -2,6 +2,7 @@ package com.gtnewhorizons.angelica.rendering.celeritas;
import com.gtnewhorizons.angelica.AngelicaMod;
import com.gtnewhorizons.angelica.glsm.GLStateManager;
import com.gtnewhorizons.angelica.proxy.ClientProxy;
import com.gtnewhorizons.angelica.rendering.celeritas.api.IrisShaderProvider;
import com.gtnewhorizons.angelica.rendering.celeritas.api.IrisShaderProviderHolder;
import me.jellysquid.mods.sodium.client.gui.options.named.MultiDrawMode;
@@ -30,7 +31,7 @@ class AngelicaChunkRenderer extends DefaultChunkRenderer {
}
private static MultiDrawEmitter createEmitter() {
MultiDrawMode mode = AngelicaMod.options().advanced.multiDrawMode;
MultiDrawMode mode = ClientProxy.options().advanced.multiDrawMode;
if (mode == MultiDrawMode.INDIRECT) {
boolean supported = GLStateManager.capabilities != null && (GLStateManager.capabilities.OpenGL43 || GLStateManager.capabilities.GL_ARB_multi_draw_indirect);
@@ -1,7 +1,7 @@
package com.gtnewhorizons.angelica.rendering.celeritas;
import com.gtnewhorizons.angelica.AngelicaMod;
import com.gtnewhorizons.angelica.mixins.interfaces.RenderSectionManagerAccessor;
import com.gtnewhorizons.angelica.proxy.ClientProxy;
import com.gtnewhorizons.angelica.rendering.AngelicaRenderQueue;
import com.gtnewhorizons.angelica.rendering.celeritas.api.IrisShaderProviderHolder;
import com.gtnewhorizons.angelica.rendering.celeritas.threading.ChunkTaskProvider;
@@ -87,7 +87,7 @@ public class AngelicaRenderSectionManager extends RenderSectionManager {
@Override
protected AsyncOcclusionMode getAsyncOcclusionMode() {
return AngelicaMod.options().performance.asyncOcclusionMode;
return ClientProxy.options().performance.asyncOcclusionMode;
}
@Override
@@ -97,7 +97,7 @@ public class AngelicaRenderSectionManager extends RenderSectionManager {
@Override
protected boolean useFogOcclusion() {
return AngelicaMod.options().performance.useFogOcclusion && !IrisShaderProviderHolder.isActive();
return ClientProxy.options().performance.useFogOcclusion && !IrisShaderProviderHolder.isActive();
}
@Override
@@ -113,7 +113,7 @@ public class AngelicaRenderSectionManager extends RenderSectionManager {
return false;
}
}
return AngelicaMod.options().performance.useOcclusionCulling;
return ClientProxy.options().performance.useOcclusionCulling;
}
@Override
@@ -152,7 +152,7 @@ public class AngelicaRenderSectionManager extends RenderSectionManager {
@Override
protected boolean allowImportantRebuilds() {
return !AngelicaMod.options().performance.alwaysDeferChunkUpdates;
return !ClientProxy.options().performance.alwaysDeferChunkUpdates;
}
@Override
@@ -2,9 +2,9 @@ package com.gtnewhorizons.angelica.rendering.celeritas;
import com.gtnewhorizons.angelica.config.AngelicaConfig;
import com.gtnewhorizons.angelica.glsm.GLStateManager;
import com.gtnewhorizons.angelica.loading.AngelicaClientTweaker;
import org.embeddedt.embeddium.impl.gl.device.GLRenderDevice;
import org.lwjgl.opengl.GL15;
import static com.gtnewhorizons.angelica.loading.AngelicaTweaker.LOGGER;
public class CeleritasSetup {
private static boolean initialized = false;
@@ -12,7 +12,7 @@ public class CeleritasSetup {
public static void ensureInitialized() {
if (!initialized && AngelicaConfig.enableCeleritas) {
GLRenderDevice.VANILLA_STATE_RESETTER = () -> GLStateManager.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
LOGGER.debug("Celeritas init");
AngelicaClientTweaker.LOGGER.debug("Celeritas init");
initialized = true;
}
}
@@ -1,10 +1,10 @@
package com.gtnewhorizons.angelica.rendering.celeritas;
import com.gtnewhorizons.angelica.AngelicaMod;
import com.gtnewhorizons.angelica.dynamiclights.DynamicLights;
import com.gtnewhorizons.angelica.dynamiclights.IDynamicLightWorldRenderer;
import com.gtnewhorizons.angelica.glsm.GLStateManager;
import com.gtnewhorizons.angelica.mixins.interfaces.ITileEntityBoundingBoxCache;
import com.gtnewhorizons.angelica.proxy.ClientProxy;
import com.gtnewhorizons.angelica.rendering.RenderingState;
import com.gtnewhorizons.angelica.rendering.TileEntityRenderBoundsRegistry;
import com.gtnewhorizons.angelica.rendering.celeritas.api.IrisShaderProvider;
@@ -127,7 +127,7 @@ public class CeleritasWorldRenderer extends SimpleWorldRenderer<WorldClient, Ang
}
}
if (AngelicaMod.options().performance.useCompactVertexFormat) {
if (ClientProxy.options().performance.useCompactVertexFormat) {
return ChunkMeshFormats.COMPACT;
}
return ChunkMeshFormats.VANILLA_LIKE;
@@ -155,7 +155,7 @@ public class CeleritasWorldRenderer extends SimpleWorldRenderer<WorldClient, Ang
renderSectionManager.setCameraPosition(transform.x, transform.y, transform.z);
this.useEntityCulling = AngelicaMod.options().performance.useEntityCulling;
this.useEntityCulling = ClientProxy.options().performance.useEntityCulling;
super.setupTerrain(viewport, cameraState, frame, spectator, updateChunksImmediately);
@@ -313,7 +313,7 @@ public class CeleritasWorldRenderer extends SimpleWorldRenderer<WorldClient, Ang
public int renderBlockEntities(float partialTicks) {
final int pass = MinecraftForgeClient.getRenderPass();
teRenderContext.set(partialTicks, pass);
if (pass == 0 || !AngelicaMod.options().performance.translucencySorting) {
if (pass == 0 || !ClientProxy.options().performance.translucencySorting) {
return super.renderBlockEntities(teRenderContext);
}
int count = 0;
@@ -56,16 +56,19 @@ final class Enchantment extends OverrideBase {
GLStateManager.glEnable(GL11.GL_ALPHA_TEST);
GLStateManager.glAlphaFunc(GL11.GL_GREATER, 0.01f);
GLStateManager.glEnable(GL11.GL_BLEND);
GLStateManager.glDepthFunc(GL11.GL_EQUAL);
lightingWasEnabled = GLStateManager.glGetBoolean(GL11.GL_LIGHTING);
GLStateManager.glDisable(GL11.GL_LIGHTING);
GLStateManager.glMatrixMode(GL11.GL_TEXTURE);
GLStateManager.glStencilFunc(GL11.GL_EQUAL, 1, 0xFF);
GLStateManager.glStencilOp(GL11.GL_KEEP, GL11.GL_KEEP, GL11.GL_KEEP);
}
static void endOuter3D() {
GLStateManager.glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
GLStateManager.glDisable(GL11.GL_BLEND);
GLStateManager.glDepthFunc(GL11.GL_LEQUAL);
GLStateManager.glDepthMask(true);
GLStateManager.glDisable(GL11.GL_STENCIL_TEST);
if (lightingWasEnabled) {
GLStateManager.glEnable(GL11.GL_LIGHTING);
}
@@ -139,6 +142,17 @@ final class Enchantment extends OverrideBase {
return;
}
begin(intensity);
// Depth pre-pass
GLStateManager.glColorMask(false, false, false, false);
GLStateManager.glDepthMask(true);
GLStateManager.glDepthFunc(GL11.GL_LEQUAL);
ItemRenderer.renderItemIn2D(Tessellator.instance, 1.0f, 0.0f, 0.0f, 1.0f, width, height, ITEM_2D_THICKNESS);
// Color pass
GLStateManager.glColorMask(true, true, true, true);
GLStateManager.glDepthMask(false);
GLStateManager.glDepthFunc(GL11.GL_EQUAL);
ItemRenderer.renderItemIn2D(Tessellator.instance, 1.0f, 0.0f, 0.0f, 1.0f, width, height, ITEM_2D_THICKNESS);
end();
}
@@ -26,7 +26,6 @@ import org.lwjgl.opengl.EXTFramebufferObject;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL12;
import org.lwjgl.opengl.GL13;
import org.lwjgl.opengl.GLContext;
import org.lwjgl.util.glu.GLU;
import com.gtnewhorizons.angelica.glsm.GLStateManager;
@@ -47,8 +46,8 @@ public class FancyDial {
private static final double ANGLE_UNSET = Double.MAX_VALUE;
private static final int NUM_SCRATCH_TEXTURES = 3;
private static final boolean fboSupported = GLContext.getCapabilities().GL_EXT_framebuffer_object;
private static final boolean gl13Supported = GLContext.getCapabilities().OpenGL13;
private static final boolean fboSupported = GLStateManager.capabilities.GL_EXT_framebuffer_object;
private static final boolean gl13Supported = GLStateManager.capabilities.OpenGL13;
private static final boolean enableCompass = MCPatcherForgeConfig.ExtendedHD.fancyCompass;
private static final boolean enableClock = MCPatcherForgeConfig.ExtendedHD.fancyClock;
private static final boolean useGL13 = gl13Supported && MCPatcherForgeConfig.ExtendedHD.useGL13;
@@ -148,7 +147,7 @@ public class FancyDial {
FancyDial instance = getInstance(icon);
return instance != null && instance.render(itemFrameRenderer);
} finally {
EXTFramebufferObject.glBindFramebufferEXT(EXTFramebufferObject.GL_FRAMEBUFFER_EXT, oldFB);
GLStateManager.glBindFramebuffer(EXTFramebufferObject.GL_FRAMEBUFFER_EXT, oldFB);
GLAPI.glBindTexture(oldTexture);
}
}
@@ -603,13 +602,13 @@ public class FancyDial {
this.width = width;
this.height = height;
frameBuffer = EXTFramebufferObject.glGenFramebuffersEXT();
frameBuffer = GLStateManager.glGenFramebuffers();
if (frameBuffer < 0) {
throw new RuntimeException("could not get framebuffer object");
}
GLAPI.glBindTexture(texture);
EXTFramebufferObject.glBindFramebufferEXT(EXTFramebufferObject.GL_FRAMEBUFFER_EXT, frameBuffer);
EXTFramebufferObject.glFramebufferTexture2DEXT(
GLStateManager.glBindFramebuffer(EXTFramebufferObject.GL_FRAMEBUFFER_EXT, frameBuffer);
GLStateManager.glFramebufferTexture2D(
EXTFramebufferObject.GL_FRAMEBUFFER_EXT,
EXTFramebufferObject.GL_COLOR_ATTACHMENT0_EXT,
GL11.GL_TEXTURE_2D,
@@ -618,7 +617,7 @@ public class FancyDial {
}
void bind() {
EXTFramebufferObject.glBindFramebufferEXT(EXTFramebufferObject.GL_FRAMEBUFFER_EXT, frameBuffer);
GLStateManager.glBindFramebuffer(EXTFramebufferObject.GL_FRAMEBUFFER_EXT, frameBuffer);
GLStateManager.glPushAttrib(glAttributes);
GLStateManager.glViewport(x0, y0, width, height);
@@ -674,11 +673,11 @@ public class FancyDial {
GLStateManager.glEnable(GL11.GL_BLEND);
GLAPI.glBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ZERO);
EXTFramebufferObject.glBindFramebufferEXT(EXTFramebufferObject.GL_FRAMEBUFFER_EXT, 0);
GLStateManager.glBindFramebuffer(EXTFramebufferObject.GL_FRAMEBUFFER_EXT, 0);
}
void read(ByteBuffer buffer) {
EXTFramebufferObject.glBindFramebufferEXT(EXTFramebufferObject.GL_FRAMEBUFFER_EXT, frameBuffer);
GLStateManager.glBindFramebuffer(EXTFramebufferObject.GL_FRAMEBUFFER_EXT, frameBuffer);
buffer.position(0);
GLStateManager.glReadPixels(x0, y0, width, height, MipmapHelper.TEX_FORMAT, MipmapHelper.TEX_DATA_TYPE, buffer);
}
@@ -704,7 +703,7 @@ public class FancyDial {
if (ownTexture) {
GLStateManager.glDeleteTextures(texture);
}
EXTFramebufferObject.glDeleteFramebuffersEXT(frameBuffer);
GLStateManager.glDeleteFramebuffers(frameBuffer);
}
}
@@ -11,7 +11,6 @@ import org.lwjgl.opengl.EXTTextureFilterAnisotropic;
import org.lwjgl.opengl.EXTTextureLODBias;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL12;
import org.lwjgl.opengl.GLContext;
import org.lwjgl.util.glu.GLU;
import com.gtnewhorizons.angelica.glsm.GLStateManager;
@@ -47,10 +46,10 @@ public class MipmapHelper {
private static final Map<String, Boolean> mipmapType = new HashMap<>();
static {
mipmapSupported = GLContext.getCapabilities().OpenGL12;
mipmapSupported = GLStateManager.capabilities.OpenGL12;
useMipmap = mipmapSupported && mipmapEnabled && maxMipmapLevel > 0;
anisoSupported = GLContext.getCapabilities().GL_EXT_texture_filter_anisotropic;
anisoSupported = GLStateManager.capabilities.GL_EXT_texture_filter_anisotropic;
if (anisoSupported) {
anisoMax = (int) GLStateManager.glGetFloat(EXTTextureFilterAnisotropic.GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT);
checkGLError("glGetFloat(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT)");
@@ -59,7 +58,7 @@ public class MipmapHelper {
anisoMax = anisoLevel = 1;
}
lodSupported = GLContext.getCapabilities().GL_EXT_texture_lod_bias;
lodSupported = GLStateManager.capabilities.GL_EXT_texture_lod_bias;
if (lodSupported) {
lodBias = MCPatcherForgeConfig.ExtendedHD.lodBias;
} else {
@@ -1,13 +1,11 @@
package com.prupe.mcpatcher.mal.resource;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GLContext;
import com.gtnewhorizons.angelica.glsm.GLStateManager;
public class GLAPI {
private static final boolean useGlBlendFuncSeparate = GLContext.getCapabilities().OpenGL14;
private static final boolean useGlBlendFuncSeparate = GLStateManager.capabilities.OpenGL14;
public static void glBindTexture(int texture) {
if (texture >= 0) {
+2 -2
View File
@@ -2,7 +2,7 @@ package jss.notfine.asm;
import java.util.Objects;
import com.gtnewhorizons.angelica.loading.AngelicaTweaker;
import com.gtnewhorizons.angelica.loading.AngelicaClientTweaker;
import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.FieldInsnNode;
import org.objectweb.asm.tree.FrameNode;
@@ -133,7 +133,7 @@ public class ASMUtils {
yield false;
}
default -> {
AngelicaTweaker.LOGGER.warn("Unchecked node found: " + node1.getClass());
AngelicaClientTweaker.LOGGER.warn("Unchecked node found: " + node1.getClass());
yield node1.toString()
.equals(node2.toString());
}
@@ -1,10 +1,10 @@
package jss.notfine.asm.mappings;
import java.util.ArrayList;
import com.gtnewhorizons.angelica.loading.AngelicaTweaker;
import com.gtnewhorizons.angelica.loading.AngelicaClientTweaker;
import net.minecraft.launchwrapper.Launch;
import java.util.ArrayList;
/**
* This class und inherited classes are adapted from
* <a href=
@@ -48,7 +48,7 @@ public class Namer {
public static void initNames() {
final boolean obfuscated = !(Boolean) Launch.blackboard.get("fml.deobfuscatedEnvironment");
AngelicaTweaker.LOGGER.info("Environment obfuscated: {}", obfuscated);
AngelicaClientTweaker.LOGGER.info("Environment obfuscated: {}", obfuscated);
if (obfuscated) {
new NamerObf().setNames();
} else {
@@ -1,16 +1,16 @@
package jss.notfine.asm.mappings;
import com.gtnewhorizons.angelica.loading.AngelicaClientTweaker;
import jss.notfine.asm.mappings.Names.Clas;
import jss.notfine.asm.mappings.Names.Fiel;
import jss.notfine.asm.mappings.Names.Meth;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import com.gtnewhorizons.angelica.loading.AngelicaTweaker;
import jss.notfine.asm.mappings.Names.Clas;
import jss.notfine.asm.mappings.Names.Fiel;
import jss.notfine.asm.mappings.Names.Meth;
public class NamerMcp extends NamerSrg {
@Override
@@ -71,15 +71,15 @@ public class NamerMcp extends NamerSrg {
nameMap = loadReobfMap(confPath + "packaged.srg");
for (Clas c : ac) {
String s = nameMap.get(c.name);
AngelicaTweaker.LOGGER.trace("C {} {}", c.name, s);
AngelicaClientTweaker.LOGGER.trace("C {} {}", c.name, s);
}
for (Fiel f : af) {
String s = nameMap.get(f.clas + "/" + f.name);
AngelicaTweaker.LOGGER.trace("F {} {}", f.name, s);
AngelicaClientTweaker.LOGGER.trace("F {} {}", f.name, s);
}
for (Meth m : am) {
String s = nameMap.get(m.clas + "/" + m.name + m.desc);
AngelicaTweaker.LOGGER.trace("M {} {}", m.name, s);
AngelicaClientTweaker.LOGGER.trace("M {} {}", m.name, s);
}
}
@@ -1,6 +1,7 @@
package me.jellysquid.mods.sodium.client.gui.options.storage;
import com.gtnewhorizons.angelica.AngelicaMod;
import com.gtnewhorizons.angelica.proxy.ClientProxy;
import me.jellysquid.mods.sodium.client.gui.SodiumGameOptions;
import java.io.IOException;
@@ -9,7 +10,7 @@ public class SodiumOptionsStorage implements OptionStorage<SodiumGameOptions> {
private final SodiumGameOptions options;
public SodiumOptionsStorage() {
this.options = AngelicaMod.options();
this.options = ClientProxy.options();
}
@Override
+50 -15
View File
@@ -3,30 +3,30 @@ package net.coderbot.iris;
import com.google.common.base.Throwables;
import com.gtnewhorizon.gtnhlib.client.renderer.CapturingTessellator;
import com.gtnewhorizon.gtnhlib.client.renderer.TessellatorManager;
import com.gtnewhorizons.angelica.AngelicaMod;
import com.gtnewhorizons.angelica.Tags;
import com.gtnewhorizons.angelica.config.AngelicaConfig;
import com.gtnewhorizons.angelica.proxy.ClientProxy;
import com.gtnewhorizons.angelica.rendering.celeritas.api.IrisShaderProviderHolder;
import cpw.mods.fml.client.registry.ClientRegistry;
import cpw.mods.fml.common.eventhandler.SubscribeEvent;
import cpw.mods.fml.common.gameevent.InputEvent;
import it.unimi.dsi.fastutil.ints.Int2IntMap;
import it.unimi.dsi.fastutil.objects.Object2IntMap;
import it.unimi.dsi.fastutil.objects.Reference2ObjectMap;
import lombok.Getter;
import net.coderbot.iris.block_context.BlockContextHolder;
import net.coderbot.iris.block_rendering.BlockRenderingSettings;
import com.gtnewhorizons.angelica.config.AngelicaConfig;
import net.coderbot.iris.celeritas.IrisCeleritasShaderProvider;
import com.gtnewhorizons.angelica.rendering.celeritas.api.IrisShaderProviderHolder;
import net.coderbot.iris.compat.dh.DHCompat;
import net.coderbot.iris.config.IrisConfig;
import net.coderbot.iris.gbuffer_overrides.matching.InputAvailability;
import net.coderbot.iris.gl.shader.StandardMacros;
import net.coderbot.iris.gui.screen.ShaderPackScreen;
import net.coderbot.iris.pipeline.DeferredWorldRenderingPipeline;
import net.coderbot.iris.pipeline.transform.ShaderTransformer;
import net.coderbot.iris.pipeline.transform.TransformPatcher;
import net.coderbot.iris.gbuffer_overrides.matching.InputAvailability;
import net.coderbot.iris.pipeline.FixedFunctionWorldRenderingPipeline;
import net.coderbot.iris.pipeline.PipelineManager;
import net.coderbot.iris.pipeline.WorldRenderingPipeline;
import net.coderbot.iris.pipeline.transform.ShaderTransformer;
import net.coderbot.iris.pipeline.transform.TransformPatcher;
import net.coderbot.iris.shaderpack.OptionalBoolean;
import net.coderbot.iris.shaderpack.ProgramSet;
import net.coderbot.iris.shaderpack.ShaderPack;
@@ -35,7 +35,6 @@ import net.coderbot.iris.shaderpack.option.OptionSet;
import net.coderbot.iris.shaderpack.option.Profile;
import net.coderbot.iris.shaderpack.option.values.MutableOptionValues;
import net.coderbot.iris.shaderpack.option.values.OptionValues;
import net.coderbot.iris.block_context.BlockContextHolder;
import net.coderbot.iris.texture.pbr.PBRTextureManager;
import net.minecraft.block.Block;
import net.minecraft.client.Minecraft;
@@ -64,7 +63,6 @@ import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Properties;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@@ -72,6 +70,7 @@ import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinWorkerThread;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Supplier;
import java.util.stream.Stream;
import java.util.zip.ZipError;
@@ -113,11 +112,31 @@ public class Iris {
// Used in favor of queueDefaultShaderPackOptionValues() for resetting as the
// behavior is more concrete and therefore is more likely to repair a user's issues
private static boolean resetShaderPackOptions = false;
private static boolean loadShaderPackWhenPossible = false;
private static String IRIS_VERSION;
@Getter
private static boolean fallback;
public static boolean loadedIncompatiblePack() {
return DHCompat.lastPackIncompatible();
}
public static void loadShaderpackWhenPossible() {
loadShaderPackWhenPossible = true;
}
public static void tryLoadShaderpackWhenPossible() {
if (loadShaderPackWhenPossible) {
loadShaderPackWhenPossible = false;
try {
reload();
} catch (IOException e) {
logger.error("Error during deferred shader reload", e);
}
}
}
/**
* Lazy executor for parallelizing shader transformations during shader pack loading.
* Creates threads on demand and shuts down after a period of inactivity.
@@ -335,7 +354,7 @@ public class Iris {
final boolean released = !Keyboard.getEventKeyState();
if (Minecraft.getMinecraft().gameSettings.showDebugInfo && GuiScreen.isShiftKeyDown() && GuiScreen.isCtrlKeyDown() && released) {
if (key == Keyboard.KEY_N) {
AngelicaMod.animationsMode.next();
ClientProxy.animationsMode.next();
}
}
}
@@ -350,6 +369,7 @@ public class Iris {
* <p>This is called right before options are loaded, so we can add key bindings here.</p>
*/
public void onEarlyInitialize() {
DHCompat.run();
try {
if (!Files.exists(getShaderpacksDirectory())) {
Files.createDirectories(getShaderpacksDirectory());
@@ -395,8 +415,19 @@ public class Iris {
PBRTextureManager.INSTANCE.init();
// Only load the shader pack when we can access OpenGL
loadShaderpack();
boolean isDHLoaded;
try {
Class.forName("com.seibel.distanthorizons.DistantHorizonsTweaker");
isDHLoaded = true;
}
catch (Exception e) {
isDHLoaded = false;
}
// When DH is present, defer shaderpack loading until its init callback has run.
if (!isDHLoaded) {
loadShaderpack();
}
}
/**
@@ -448,11 +479,9 @@ public class Iris {
// Attempt to load an external shaderpack if it is available
final Optional<String> externalName = irisConfig.getShaderPackName();
if (!externalName.isPresent()) {
if (externalName.isEmpty()) {
logger.info("Shaders are disabled because no valid shaderpack is selected");
setShadersDisabled();
return;
}
@@ -721,6 +750,12 @@ public class Iris {
BlockRenderingSettings.INSTANCE.reloadRendererIfRequired();
}
if (loadedIncompatiblePack() && Minecraft.getMinecraft().thePlayer != null) {
Iris.logger.warn("Incompatible pack for DH!");
Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.BOLD.toString() + EnumChatFormatting.RED + "This pack doesn't have DH support."));
Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.RED + "Distant Horizons (DH) chunks won't show up. This isn't a bug, get another shader."));
}
}
/**
@@ -1,7 +1,7 @@
package net.coderbot.iris.client;
import com.gtnewhorizons.angelica.AngelicaMod;
import com.gtnewhorizons.angelica.config.AngelicaConfig;
import com.gtnewhorizons.angelica.proxy.ClientProxy;
import cpw.mods.fml.common.eventhandler.EventPriority;
import cpw.mods.fml.common.eventhandler.SubscribeEvent;
import net.coderbot.iris.Iris;
@@ -47,7 +47,7 @@ public class IrisDebugScreenHandler {
event.right.add("[" + Iris.MODNAME + "] Shaders are disabled");
}
if (AngelicaConfig.speedupAnimations) {
event.right.add(Math.min(event.right.size(), 9), "animationsMode: " + AngelicaMod.animationsMode);
event.right.add(Math.min(event.right.size(), 9), "animationsMode: " + ClientProxy.animationsMode);
}
Iris.getPipelineManager().getPipeline().ifPresent(pipeline -> pipeline.addDebugText(event.left));
@@ -1,14 +1,129 @@
package net.coderbot.iris.compat.dh;
/**
* Stub implementation of Distant Horizons compatibility.
*/
public class DHCompat {
public int getDepthTex() {
return 0;
}
import com.gtnewhorizons.angelica.rendering.RenderingState;
import net.coderbot.iris.Iris;
import net.coderbot.iris.pipeline.DeferredWorldRenderingPipeline;
import net.minecraft.client.Minecraft;
import org.joml.Matrix4f;
import org.joml.Matrix4fc;
public int getDepthTexNoTranslucent() {
return 0;
}
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.lang.reflect.InvocationTargetException;
public class DHCompat {
private static boolean dhPresent;
private static boolean lastIncompatible;
private DHCompatInternal compatInternalInstance;
private final static Matrix4f tempProj = new Matrix4f();
public DHCompat(DeferredWorldRenderingPipeline pipeline, boolean renderDHShadow) {
if (pipeline == null) {
return;
}
try {
if (dhPresent) {
compatInternalInstance = new DHCompatInternal(pipeline, renderDHShadow);
lastIncompatible = compatInternalInstance.incompatiblePack();
}
} catch (Throwable e) {
lastIncompatible = false;
if (e instanceof InvocationTargetException ite) {
throw new RuntimeException("Unknown error loading Distant Horizons compatibility.", ite.getCause());
} else {
throw new RuntimeException("Unknown error loading Distant Horizons compatibility.", e);
}
}
}
public static Matrix4fc getProjection() {
Matrix4f projection = RenderingState.INSTANCE.getProjectionMatrix();
if (!dhPresent) {
return projection;
}
return tempProj.setPerspective(projection.perspectiveFov(), projection.m11() / projection.m00(), DHCompat.getNearPlane(), DHCompat.getFarPlane());
}
public static void run() {
try {
Class.forName("com.seibel.distanthorizons.DistantHorizonsTweaker");
dhPresent = true;
}
catch (Exception e) {
dhPresent = false;
}
try {
if (dhPresent) {
LodRendererEvents.setupEventHandlers();
}
} catch (Throwable e) {
dhPresent = false;
if (e instanceof ExceptionInInitializerError eiie) {
throw new RuntimeException("Failure loading DH compat.", eiie.getCause());
} else {
throw new RuntimeException("DH found, but one or more API methods are missing. Iris requires DH [2.0.4] or DH API version [1.1.0] or newer. Please make sure you are on the latest version of DH and Iris.", e);
}
}
}
public static boolean lastPackIncompatible() {
return dhPresent && hasRenderingEnabled() && lastIncompatible;
}
public static float getFarPlane() {
if (!dhPresent) return 0.01f;
return DHCompatInternal.getFarPlane();
}
public static float getNearPlane() {
if (!dhPresent) return 0.01f;
return DHCompatInternal.getNearPlane();
}
public static int getRenderDistance() {
if (!dhPresent) return Minecraft.getMinecraft().gameSettings.renderDistanceChunks * 16;
return DHCompatInternal.getRenderDistance();
}
public static boolean checkFrame() {
if (!dhPresent) {
return false;
}
return DHCompatInternal.checkFrame();
}
public static boolean hasRenderingEnabled() {
if (!dhPresent) {
return false;
}
return checkFrame();
}
public void clearPipeline() {
if (compatInternalInstance == null) return;
compatInternalInstance.clear();
}
public int getDepthTex() {
if (compatInternalInstance == null) return -1;
return compatInternalInstance.getStoredDepthTex();
}
public int getDepthTexNoTranslucent() {
if (compatInternalInstance == null) return -1;
return compatInternalInstance.getDepthTexNoTranslucent();
}
public DHCompatInternal getInstance() {
return compatInternalInstance;
}
}
@@ -0,0 +1,291 @@
package net.coderbot.iris.compat.dh;
import com.gtnewhorizons.angelica.glsm.GLStateManager;
import com.seibel.distanthorizons.api.DhApi;
import com.seibel.distanthorizons.api.interfaces.override.rendering.IDhApiFramebuffer;
import com.seibel.distanthorizons.api.interfaces.override.rendering.IDhApiGenericObjectShaderProgram;
import com.seibel.distanthorizons.api.objects.math.DhApiVec3f;
import com.seibel.distanthorizons.coreapi.DependencyInjection.OverrideInjector;
import net.coderbot.iris.Iris;
import net.coderbot.iris.gl.framebuffer.GlFramebuffer;
import net.coderbot.iris.gl.texture.DepthBufferFormat;
import net.coderbot.iris.gl.texture.DepthCopyStrategy;
import net.coderbot.iris.pipeline.DeferredWorldRenderingPipeline;
import net.coderbot.iris.rendertarget.DepthTexture;
import net.coderbot.iris.rendertarget.IRenderTargetExt;
import net.coderbot.iris.shaderpack.CloudSetting;
import net.coderbot.iris.shaderpack.ProgramSource;
import net.coderbot.iris.uniforms.CapturedRenderingState;
import net.irisshaders.iris.api.v0.IrisApi;
import net.minecraft.client.Minecraft;
import org.lwjgl.opengl.GL11;
import java.io.IOException;
public class DHCompatInternal {
public static final DHCompatInternal SHADERLESS = new DHCompatInternal(null, false);
static boolean dhEnabled;
private static int guiScale = -1;
private final DeferredWorldRenderingPipeline pipeline;
public boolean shouldOverrideShadow;
public boolean shouldOverride;
private GlFramebuffer dhGenericFramebuffer;
private IrisLodRenderProgram solidProgram;
private IrisGenericRenderProgram genericShader;
private IrisLodRenderProgram translucentProgram;
private IrisLodRenderProgram shadowProgram;
private GlFramebuffer dhTerrainFramebuffer;
private DhFrameBufferWrapper dhTerrainFramebufferWrapper;
private GlFramebuffer dhWaterFramebuffer;
private GlFramebuffer dhShadowFramebuffer;
private DhFrameBufferWrapper dhShadowFramebufferWrapper;
private DepthTexture depthTexNoTranslucent;
private boolean translucentDepthDirty;
private int storedDepthTex = -1;
private boolean incompatible = false;
private int cachedVersion;
public DHCompatInternal(DeferredWorldRenderingPipeline pipeline, boolean dhShadowEnabled) {
this.pipeline = pipeline;
if (pipeline == null || !DhApi.Delayed.configs.graphics().renderingEnabled().getValue()) {
return;
}
if (pipeline.getDHTerrainShader().isEmpty() && pipeline.getDHWaterShader().isEmpty()) {
Iris.logger.warn("No DH shader found in this pack.");
incompatible = true;
return;
}
cachedVersion = ((IRenderTargetExt) Minecraft.getMinecraft().getFramebuffer()).iris$getDepthBufferVersion();
createDepthTex(Minecraft.getMinecraft().getFramebuffer().framebufferWidth, Minecraft.getMinecraft().getFramebuffer().framebufferHeight);
translucentDepthDirty = true;
ProgramSource terrain = pipeline.getDHTerrainShader().get();
solidProgram = IrisLodRenderProgram.createProgram(terrain.getName(), false, false, terrain, pipeline.getCustomUniforms(), pipeline);
ProgramSource generic = pipeline.getDHGenericShader().get();
genericShader = IrisGenericRenderProgram.createProgram(generic.getName() + "_g", false, false, generic, pipeline.getCustomUniforms(), pipeline);
dhGenericFramebuffer = pipeline.createDHFramebuffer(generic, false);
if (pipeline.getDHWaterShader().isPresent()) {
ProgramSource water = pipeline.getDHWaterShader().get();
translucentProgram = IrisLodRenderProgram.createProgram(water.getName(), false, true, water, pipeline.getCustomUniforms(), pipeline);
dhWaterFramebuffer = pipeline.createDHFramebuffer(water, true);
}
if (pipeline.getDHShadowShader().isPresent() && dhShadowEnabled) {
ProgramSource shadow = pipeline.getDHShadowShader().get();
shadowProgram = IrisLodRenderProgram.createProgram(shadow.getName(), true, false, shadow, pipeline.getCustomUniforms(), pipeline);
if (pipeline.hasShadowRenderTargets()) {
dhShadowFramebuffer = pipeline.createDHFramebufferShadow(shadow);
dhShadowFramebufferWrapper = new DhFrameBufferWrapper(dhShadowFramebuffer);
}
shouldOverrideShadow = true;
} else {
shouldOverrideShadow = false;
}
dhTerrainFramebuffer = pipeline.createDHFramebuffer(terrain, false);
dhTerrainFramebufferWrapper = new DhFrameBufferWrapper(dhTerrainFramebuffer);
if (translucentProgram == null) {
translucentProgram = solidProgram;
}
shouldOverride = true;
}
public static int getDhBlockRenderDistance() {
if (DhApi.Delayed.configs == null || !dhEnabled) {
// Called before DH has finished setup
return Minecraft.getMinecraft().gameSettings.renderDistanceChunks * 16;
}
return DhApi.Delayed.configs.graphics().chunkRenderDistance().getValue() * 16;
}
public static int getRenderDistance() {
return getDhBlockRenderDistance();
}
public static float getFarPlane() {
if (DhApi.Delayed.configs == null) {
// Called before DH has finished setup
return 0;
}
int lodChunkDist = DhApi.Delayed.configs.graphics().chunkRenderDistance().getValue();
int lodBlockDist = lodChunkDist * 16;
// sqrt 2 to prevent the corners from being cut off
return (float) ((lodBlockDist + 512) * Math.sqrt(2));
}
public static float getNearPlane() {
if (DhApi.Delayed.renderProxy == null) {
// Called before DH has finished setup
return 0;
}
return DhApi.Delayed.renderProxy.getNearClipPlaneDistanceInBlocks(CapturedRenderingState.INSTANCE.getTickDelta());
}
public static boolean checkFrame() {
if (guiScale == -1) {
guiScale = Minecraft.getMinecraft().gameSettings.guiScale;
}
if (DhApi.Delayed.configs == null) return dhEnabled;
if ((dhEnabled != DhApi.Delayed.configs.graphics().renderingEnabled().getValue() || guiScale != Minecraft.getMinecraft().gameSettings.guiScale)
&& IrisApi.getInstance().isShaderPackInUse()) {
guiScale = Minecraft.getMinecraft().gameSettings.guiScale;
dhEnabled = DhApi.Delayed.configs.graphics().renderingEnabled().getValue();
try {
Iris.reload();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
return dhEnabled;
}
public boolean incompatiblePack() {
return incompatible;
}
public void reconnectDHTextures(int depthTex) {
if (((IRenderTargetExt) Minecraft.getMinecraft().getFramebuffer()).iris$getDepthBufferVersion() != cachedVersion) {
cachedVersion = ((IRenderTargetExt) Minecraft.getMinecraft().getFramebuffer()).iris$getDepthBufferVersion();
createDepthTex(Minecraft.getMinecraft().getFramebuffer().framebufferWidth, Minecraft.getMinecraft().getFramebuffer().framebufferHeight);
}
if (storedDepthTex != depthTex && dhTerrainFramebuffer != null) {
storedDepthTex = depthTex;
dhTerrainFramebuffer.addDepthAttachmentBypass(depthTex);
if (dhWaterFramebuffer != null) {
dhWaterFramebuffer.addDepthAttachmentBypass(depthTex);
}
if (dhGenericFramebuffer != null) {
dhGenericFramebuffer.addDepthAttachmentBypass(depthTex);
}
}
}
public void createDepthTex(int width, int height) {
if (depthTexNoTranslucent != null) {
depthTexNoTranslucent.destroy();
depthTexNoTranslucent = null;
}
translucentDepthDirty = true;
depthTexNoTranslucent = new DepthTexture(width, height, DepthBufferFormat.DEPTH32F);
}
public void clear() {
if (solidProgram != null) {
solidProgram.free();
solidProgram = null;
}
if (translucentProgram != null) {
translucentProgram.free();
translucentProgram = null;
}
if (shadowProgram != null) {
shadowProgram.free();
shadowProgram = null;
}
shouldOverrideShadow = false;
shouldOverride = false;
dhTerrainFramebuffer = null;
dhWaterFramebuffer = null;
dhShadowFramebuffer = null;
storedDepthTex = -1;
translucentDepthDirty = true;
OverrideInjector.INSTANCE.unbind(IDhApiFramebuffer.class, dhTerrainFramebufferWrapper);
OverrideInjector.INSTANCE.unbind(IDhApiGenericObjectShaderProgram.class, genericShader);
OverrideInjector.INSTANCE.unbind(IDhApiFramebuffer.class, dhShadowFramebufferWrapper);
dhTerrainFramebufferWrapper = null;
dhShadowFramebufferWrapper = null;
}
public void setModelPos(DhApiVec3f modelPos) {
solidProgram.bind();
solidProgram.setModelPos(modelPos);
translucentProgram.bind();
translucentProgram.setModelPos(modelPos);
solidProgram.bind();
}
public IrisLodRenderProgram getSolidShader() {
return solidProgram;
}
public GlFramebuffer getSolidFB() {
return dhTerrainFramebuffer;
}
public DhFrameBufferWrapper getSolidFBWrapper() {
return dhTerrainFramebufferWrapper;
}
public IrisLodRenderProgram getShadowShader() {
return shadowProgram;
}
public GlFramebuffer getShadowFB() {
return dhShadowFramebuffer;
}
public DhFrameBufferWrapper getShadowFBWrapper() {
return dhShadowFramebufferWrapper;
}
public IrisLodRenderProgram getTranslucentShader() {
if (translucentProgram == null) {
return solidProgram;
}
return translucentProgram;
}
public int getStoredDepthTex() {
return storedDepthTex;
}
public void copyTranslucents(int width, int height) {
if (translucentDepthDirty) {
translucentDepthDirty = false;
GLStateManager.glBindTexture(GL11.GL_TEXTURE_2D, depthTexNoTranslucent.getTextureId());
dhTerrainFramebuffer.bindAsReadBuffer();
GLStateManager.glCopyTexImage2D(GL11.GL_TEXTURE_2D, 0, DepthBufferFormat.DEPTH32F.getGlInternalFormat(), 0, 0, width, height, 0);
} else {
DepthCopyStrategy.fastest(false).copy(dhTerrainFramebuffer, storedDepthTex, null, depthTexNoTranslucent.getTextureId(), width, height);
}
}
public GlFramebuffer getTranslucentFB() {
return dhWaterFramebuffer;
}
public GlFramebuffer getGenericFB() {
return dhGenericFramebuffer;
}
public int getDepthTexNoTranslucent() {
if (depthTexNoTranslucent == null) return 0;
return depthTexNoTranslucent.getTextureId();
}
public IDhApiGenericObjectShaderProgram getGenericShader() {
return genericShader;
}
public boolean avoidRenderingClouds() {
return pipeline != null && (pipeline.getDHCloudSetting() == CloudSetting.OFF || (pipeline.getDHCloudSetting() == CloudSetting.DEFAULT && pipeline.getCloudSetting() == CloudSetting.OFF));
}
}
@@ -0,0 +1,55 @@
package net.coderbot.iris.compat.dh;
import com.gtnewhorizons.angelica.glsm.GLStateManager;
import com.seibel.distanthorizons.api.interfaces.override.rendering.IDhApiFramebuffer;
import net.coderbot.iris.gl.framebuffer.GlFramebuffer;
import org.lwjgl.opengl.GL30;
public class DhFrameBufferWrapper implements IDhApiFramebuffer {
private final GlFramebuffer framebuffer;
public DhFrameBufferWrapper(GlFramebuffer framebuffer) {
this.framebuffer = framebuffer;
}
@Override
public boolean overrideThisFrame() {
return true;
}
@Override
public void bind() {
this.framebuffer.bind();
}
@Override
public void addDepthAttachment(int i, boolean b) {
// ignore
}
@Override
public int getId() {
return this.framebuffer.getId();
}
@Override
public int getStatus() {
this.bind();
int status = GLStateManager.glCheckFramebufferStatus(GL30.GL_FRAMEBUFFER);
return status;
}
@Override
public void addColorAttachment(int i, int i1) {
// ignore
}
@Override
public void destroy() {
// ignore
//this.framebuffer.destroy();
}
}
@@ -0,0 +1,351 @@
package net.coderbot.iris.compat.dh;
import com.google.common.primitives.Ints;
import com.gtnewhorizons.angelica.glsm.GLStateManager;
import com.gtnewhorizons.angelica.mixins.interfaces.EntityRendererAccessor;
import com.mitchej123.lwjgl.MemoryStack;
import com.seibel.distanthorizons.api.interfaces.override.rendering.IDhApiGenericObjectShaderProgram;
import com.seibel.distanthorizons.api.interfaces.render.IDhApiRenderableBoxGroup;
import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiRenderParam;
import com.seibel.distanthorizons.api.objects.math.DhApiMat4f;
import com.seibel.distanthorizons.api.objects.math.DhApiVec3d;
import com.seibel.distanthorizons.api.objects.render.DhApiRenderableBox;
import com.seibel.distanthorizons.api.objects.render.DhApiRenderableBoxGroupShading;
import net.coderbot.iris.gl.blending.BlendModeOverride;
import net.coderbot.iris.gl.blending.BufferBlendOverride;
import net.coderbot.iris.gl.program.ProgramImages;
import net.coderbot.iris.gl.program.ProgramSamplers;
import net.coderbot.iris.gl.program.ProgramUniforms;
import net.coderbot.iris.gl.shader.GlShader;
import net.coderbot.iris.gl.shader.ShaderType;
import net.coderbot.iris.gl.state.FogMode;
import net.coderbot.iris.pipeline.DeferredWorldRenderingPipeline;
import net.coderbot.iris.pipeline.PatchedShaderPrinter;
import net.coderbot.iris.pipeline.transform.PatchShaderType;
import net.coderbot.iris.pipeline.transform.TransformPatcher;
import net.coderbot.iris.samplers.IrisSamplers;
import net.coderbot.iris.shaderpack.ProgramSource;
import net.coderbot.iris.uniforms.CommonUniforms;
import net.coderbot.iris.uniforms.builtin.BuiltinReplacementUniforms;
import net.coderbot.iris.uniforms.custom.CustomUniforms;
import net.irisshaders.iris.api.v0.IrisApi;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.texture.DynamicTexture;
import org.joml.Matrix3f;
import org.joml.Matrix4f;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL13;
import org.lwjgl.opengl.GL15;
import org.lwjgl.opengl.GL20;
import org.lwjgl.opengl.GL30;
import java.nio.FloatBuffer;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public class IrisGenericRenderProgram implements IDhApiGenericObjectShaderProgram {
// Uniforms
public final int modelViewUniform;
public final int modelViewInverseUniform;
public final int projectionUniform;
public final int projectionInverseUniform;
public final int normalMatrix3fUniform;
// Fog/Clip Uniforms
private final int id;
private final ProgramUniforms uniforms;
private final CustomUniforms customUniforms;
private final ProgramSamplers samplers;
private final ProgramImages images;
private final BlendModeOverride blend;
private final BufferBlendOverride[] bufferBlendOverrides;
private final Matrix4f tempModel = new Matrix4f();
private final Matrix4f tempProj = new Matrix4f();
private final Matrix4f tempMat4 = new Matrix4f();
private final Matrix3f tempMat3 = new Matrix3f();
private final int instancedShaderOffsetChunkUniform;
private final int instancedShaderOffsetSubChunkUniform;
private final int instancedShaderCameraChunkPosUniform;
private final int instancedShaderCameraSubChunkPosUniform;
private final int instancedShaderProjectionModelViewMatrixUniform;
private final int va;
private final int uBlockLight;
private final int uSkyLight;
// This will bind AbstractVertexAttribute
private IrisGenericRenderProgram(String name, boolean isShadowPass, boolean translucent, BlendModeOverride override, BufferBlendOverride[] bufferBlendOverrides, String vertex, String tessControl, String tessEval, String geometry, String fragment, CustomUniforms customUniforms, DeferredWorldRenderingPipeline pipeline) {
id = GLStateManager.glCreateProgram();
GLStateManager.glBindAttribLocation(this.id, 0, "vPosition");
this.bufferBlendOverrides = bufferBlendOverrides;
GlShader vert = new GlShader(ShaderType.VERTEX, name + ".vsh", vertex);
GLStateManager.glAttachShader(id, vert.getHandle());
GlShader tessCont = null;
if (tessControl != null) {
tessCont = new GlShader(ShaderType.TESSELATION_CONTROL, name + ".tcs", tessControl);
GLStateManager.glAttachShader(id, tessCont.getHandle());
}
GlShader tessE = null;
if (tessEval != null) {
tessE = new GlShader(ShaderType.TESSELATION_EVAL, name + ".tes", tessEval);
GLStateManager.glAttachShader(id, tessE.getHandle());
}
GlShader geom = null;
if (geometry != null) {
geom = new GlShader(ShaderType.GEOMETRY, name + ".gsh", geometry);
GLStateManager.glAttachShader(id, geom.getHandle());
}
GlShader frag = new GlShader(ShaderType.FRAGMENT, name + ".fsh", fragment);
GLStateManager.glAttachShader(id, frag.getHandle());
GLStateManager.glLinkProgram(this.id);
int status = GLStateManager.glGetProgrami(this.id, GL20.GL_LINK_STATUS);
if (status != 1) {
String message = "Shader link error in Iris DH program! Details: " + GLStateManager.glGetProgramInfoLog(this.id, 9999);
this.free();
throw new RuntimeException(message);
} else {
GLStateManager.glUseProgram(this.id);
}
vert.destroy();
frag.destroy();
if (tessCont != null) tessCont.destroy();
if (tessE != null) tessE.destroy();
if (geom != null) geom.destroy();
blend = override;
ProgramUniforms.Builder uniformBuilder = ProgramUniforms.builder(name, id);
ProgramSamplers.Builder samplerBuilder = ProgramSamplers.builder(id, IrisSamplers.WORLD_RESERVED_TEXTURE_UNITS);
CommonUniforms.addDynamicUniforms(uniformBuilder, FogMode.PER_VERTEX);
customUniforms.assignTo(uniformBuilder);
BuiltinReplacementUniforms.addBuiltinReplacementUniforms(uniformBuilder);
ProgramImages.Builder builder = ProgramImages.builder(id);
pipeline.addGbufferOrShadowSamplers(samplerBuilder, builder,
isShadowPass ? pipeline::getFlippedBeforeShadow : () -> translucent ? pipeline.getFlippedAfterTranslucent() : pipeline.getFlippedAfterPrepare(),
isShadowPass, true, true, false);
customUniforms.mapholderToPass(uniformBuilder, this);
this.uniforms = uniformBuilder.buildUniforms();
this.customUniforms = customUniforms;
samplers = samplerBuilder.build();
images = builder.build();
this.va = GLStateManager.glGenVertexArrays();
GLStateManager.glBindVertexArray(va);
GLStateManager.glVertexAttribPointer(0, 3, GL11.GL_FLOAT, false, 0, 0);
GLStateManager.glEnableVertexAttribArray(0);
projectionUniform = tryGetUniformLocation2("iris_ProjectionMatrix");
projectionInverseUniform = tryGetUniformLocation2("iris_ProjectionMatrixInverse");
modelViewUniform = tryGetUniformLocation2("iris_ModelViewMatrix");
modelViewInverseUniform = tryGetUniformLocation2("iris_ModelViewMatrixInverse");
normalMatrix3fUniform = tryGetUniformLocation2("iris_NormalMatrix");
this.instancedShaderOffsetChunkUniform = this.tryGetUniformLocation2("uOffsetChunk");
this.instancedShaderOffsetSubChunkUniform = this.tryGetUniformLocation2("uOffsetSubChunk");
this.instancedShaderCameraChunkPosUniform = this.tryGetUniformLocation2("uCameraPosChunk");
this.instancedShaderCameraSubChunkPosUniform = this.tryGetUniformLocation2("uCameraPosSubChunk");
this.instancedShaderProjectionModelViewMatrixUniform = this.tryGetUniformLocation2("uProjectionMvm");
this.uBlockLight = this.tryGetUniformLocation2("uBlockLight");
this.uSkyLight = this.tryGetUniformLocation2("uSkyLight");
}
public static IrisGenericRenderProgram createProgram(String name, boolean isShadowPass, boolean translucent, ProgramSource source, CustomUniforms uniforms, DeferredWorldRenderingPipeline pipeline) {
Map<PatchShaderType, String> transformed = TransformPatcher.patchDHGeneric(
name,
source.getVertexSource().orElseThrow(RuntimeException::new),
source.getTessControlSource().orElse(null),
source.getTessEvalSource().orElse(null),
source.getGeometrySource().orElse(null),
source.getFragmentSource().orElseThrow(RuntimeException::new),
pipeline.getTextureMap());
String vertex = transformed.get(PatchShaderType.VERTEX);
String tessControl = transformed.get(PatchShaderType.TESS_CONTROL);
String tessEval = transformed.get(PatchShaderType.TESS_EVAL);
String geometry = transformed.get(PatchShaderType.GEOMETRY);
String fragment = transformed.get(PatchShaderType.FRAGMENT);
PatchedShaderPrinter.debugPatchedShaders(source.getName() + "_g", vertex, geometry, tessControl, tessEval, fragment);
List<BufferBlendOverride> bufferOverrides = new ArrayList<>();
source.getDirectives().getBufferBlendOverrides().forEach(information -> {
int index = Ints.indexOf(source.getDirectives().getDrawBuffers(), information.getIndex());
if (index > -1) {
bufferOverrides.add(new BufferBlendOverride(index, information.getBlendMode()));
}
});
return new IrisGenericRenderProgram(name, isShadowPass, translucent, source.getDirectives().getBlendModeOverride().orElse(null), bufferOverrides.toArray(BufferBlendOverride[]::new), vertex, tessControl, tessEval, geometry, fragment, uniforms, pipeline);
}
// Noise Uniforms
private static int getChunkPosFromDouble(double value) {
return (int) Math.floor(value / 16);
}
private static float getSubChunkPosFromDouble(double value) {
double chunkPos = Math.floor(value / 16);
return (float) (value - chunkPos * 16);
}
public int tryGetUniformLocation2(CharSequence name) {
return GLStateManager.glGetUniformLocation(this.id, name);
}
public void setUniform(int index, Matrix4f matrix) {
if (index == -1 || matrix == null) return;
try (MemoryStack stack = MemoryStack.stackPush()) {
FloatBuffer buffer = stack.callocFloat(16);
matrix.get(buffer);
buffer.rewind();
GLStateManager.glUniformMatrix4(index, false, buffer);
}
}
public void setUniform(int index, Matrix3f matrix) {
if (index == -1) return;
try (MemoryStack stack = MemoryStack.stackPush()) {
FloatBuffer buffer = stack.callocFloat(9);
matrix.get(buffer);
buffer.rewind();
GLStateManager.glUniformMatrix3(index, false, buffer);
}
}
// Override ShaderProgram.bind()
public void bind(DhApiRenderParam renderParam) {
GLStateManager.glBindVertexArray(va);
GLStateManager.glUseProgram(id);
if (blend != null) blend.apply();
for (BufferBlendOverride override : bufferBlendOverrides) {
override.apply();
}
toJOML(tempModel, renderParam.dhModelViewMatrix);
toJOML(tempProj, renderParam.dhProjectionMatrix);
setUniform(modelViewUniform, tempModel);
setUniform(projectionUniform, tempProj);
this.setUniform(this.instancedShaderProjectionModelViewMatrixUniform, tempMat4.set(tempProj).mul(tempModel));
tempModel.invert();
tempProj.invert();
setUniform(modelViewInverseUniform, tempModel);
setUniform(projectionInverseUniform, tempProj);
setUniform(normalMatrix3fUniform, tempModel.transpose3x3(tempMat3));
GLStateManager.glActiveTexture(GL13.GL_TEXTURE0 + IrisSamplers.LIGHTMAP_TEXTURE_UNIT);
DynamicTexture lightmapTexture = ((EntityRendererAccessor) Minecraft.getMinecraft().entityRenderer).getLightmapTexture();
GLStateManager.glBindTexture(GL11.GL_TEXTURE_2D, lightmapTexture.getGlTextureId());
samplers.update();
uniforms.update();
customUniforms.push(this);
images.update();
}
public void unbind() {
GLStateManager.glBindVertexArray(0);
GLStateManager.glUseProgram(0);
ProgramUniforms.clearActiveUniforms();
ProgramSamplers.clearActiveSamplers();
BlendModeOverride.restore();
}
@Override
public void bindVertexBuffer(int i) {
GLStateManager.glBindBuffer(GL15.GL_ARRAY_BUFFER, i);
GLStateManager.glVertexAttribPointer(0, 3, GL11.GL_FLOAT, false, 12, 0);
}
@Override
public boolean overrideThisFrame() {
return IrisApi.getInstance().isShaderPackInUse();
}
@Override
public int getId() {
return id;
}
public void free() {
GLStateManager.glDeleteProgram(id);
}
public void fillIndirectUniformData(DhApiRenderParam dhApiRenderParam, DhApiRenderableBoxGroupShading dhApiRenderableBoxGroupShading, IDhApiRenderableBoxGroup boxGroup, DhApiVec3d camPos) {
bind(dhApiRenderParam);
GLStateManager.enableDepthTest();
GLStateManager.glDepthFunc(GL11.GL_LEQUAL);
this.setUniform(this.instancedShaderOffsetChunkUniform,
getChunkPosFromDouble(boxGroup.getOriginBlockPos().x),
getChunkPosFromDouble(boxGroup.getOriginBlockPos().y),
getChunkPosFromDouble(boxGroup.getOriginBlockPos().z)
);
this.setUniform(this.instancedShaderOffsetSubChunkUniform,
getSubChunkPosFromDouble(boxGroup.getOriginBlockPos().x),
getSubChunkPosFromDouble(boxGroup.getOriginBlockPos().y),
getSubChunkPosFromDouble(boxGroup.getOriginBlockPos().z)
);
this.setUniform(this.instancedShaderCameraChunkPosUniform,
getChunkPosFromDouble(camPos.x),
getChunkPosFromDouble(camPos.y),
getChunkPosFromDouble(camPos.z)
);
this.setUniform(this.instancedShaderCameraSubChunkPosUniform,
getSubChunkPosFromDouble(camPos.x),
getSubChunkPosFromDouble(camPos.y),
getSubChunkPosFromDouble(camPos.z)
);
this.setUniform(this.uBlockLight,
boxGroup.getBlockLight());
this.setUniform(this.uSkyLight,
boxGroup.getSkyLight());
}
@Override
public void fillSharedDirectUniformData(DhApiRenderParam dhApiRenderParam, DhApiRenderableBoxGroupShading dhApiRenderableBoxGroupShading, IDhApiRenderableBoxGroup iDhApiRenderableBoxGroup, DhApiVec3d dhApiVec3d) {
throw new IllegalStateException("Only indirect is supported with Iris.");
}
@Override
public void fillDirectUniformData(DhApiRenderParam dhApiRenderParam, IDhApiRenderableBoxGroup iDhApiRenderableBoxGroup, DhApiRenderableBox dhApiRenderableBox, DhApiVec3d dhApiVec3d) {
throw new IllegalStateException("Only indirect is supported with Iris.");
}
private void toJOML(Matrix4f target, DhApiMat4f mat4f) {
target.setTransposed(mat4f.getValuesAsArray());
}
private void setUniform(int index, int value) {
GLStateManager.glUniform1i(index, value);
}
private void setUniform(int index, float value) {
GLStateManager.glUniform1f(index, value);
}
private void setUniform(int index, float x, float y, float z) {
GLStateManager.glUniform3f(index, x, y, z);
}
private void setUniform(int index, int x, int y, int z) {
GLStateManager.glUniform3i(index, x, y, z);
}
}
@@ -0,0 +1,266 @@
package net.coderbot.iris.compat.dh;
import com.google.common.primitives.Ints;
import com.gtnewhorizons.angelica.glsm.GLStateManager;
import com.gtnewhorizons.angelica.mixins.interfaces.EntityRendererAccessor;
import com.mitchej123.lwjgl.MemoryStack;
import com.seibel.distanthorizons.api.DhApi;
import com.seibel.distanthorizons.api.objects.math.DhApiVec3f;
import net.coderbot.iris.gl.blending.BlendModeOverride;
import net.coderbot.iris.gl.blending.BufferBlendOverride;
import net.coderbot.iris.gl.program.ProgramImages;
import net.coderbot.iris.gl.program.ProgramSamplers;
import net.coderbot.iris.gl.program.ProgramUniforms;
import net.coderbot.iris.gl.shader.GlShader;
import net.coderbot.iris.gl.shader.ShaderType;
import net.coderbot.iris.gl.state.FogMode;
import net.coderbot.iris.gl.texture.TextureType;
import net.coderbot.iris.pipeline.DeferredWorldRenderingPipeline;
import net.coderbot.iris.pipeline.PatchedShaderPrinter;
import net.coderbot.iris.pipeline.transform.PatchShaderType;
import net.coderbot.iris.pipeline.transform.TransformPatcher;
import net.coderbot.iris.samplers.IrisSamplers;
import net.coderbot.iris.shaderpack.ProgramSource;
import net.coderbot.iris.uniforms.CommonUniforms;
import net.coderbot.iris.uniforms.builtin.BuiltinReplacementUniforms;
import net.coderbot.iris.uniforms.custom.CustomUniforms;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.texture.DynamicTexture;
import org.joml.Matrix3f;
import org.joml.Matrix4f;
import org.joml.Matrix4fc;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL13;
import org.lwjgl.opengl.GL20;
import org.lwjgl.opengl.GL32;
import java.nio.FloatBuffer;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public class IrisLodRenderProgram {
// Uniforms
public final int modelOffsetUniform;
public final int worldYOffsetUniform;
public final int mircoOffsetUniform;
public final int modelViewUniform;
public final int modelViewInverseUniform;
public final int projectionUniform;
public final int projectionInverseUniform;
public final int normalMatrix3fUniform;
// Fog/Clip Uniforms
public final int clipDistanceUniform;
private final int id;
private final ProgramUniforms uniforms;
private final CustomUniforms customUniforms;
private final ProgramSamplers samplers;
private final ProgramImages images;
private final BlendModeOverride blend;
private final BufferBlendOverride[] bufferBlendOverrides;
private final Matrix4f tempMat4a = new Matrix4f();
private final Matrix4f tempMat4b = new Matrix4f();
private final Matrix3f tempMat3 = new Matrix3f();
// This will bind AbstractVertexAttribute
private IrisLodRenderProgram(String name, boolean isShadowPass, boolean translucent, BlendModeOverride override, BufferBlendOverride[] bufferBlendOverrides, String vertex, String tessControl, String tessEval, String geometry, String fragment, CustomUniforms customUniforms, DeferredWorldRenderingPipeline pipeline) {
id = GLStateManager.glCreateProgram();
GLStateManager.glBindAttribLocation(this.id, 0, "vPosition");
GLStateManager.glBindAttribLocation(this.id, 1, "iris_color");
GLStateManager.glBindAttribLocation(this.id, 2, "irisExtra");
this.bufferBlendOverrides = bufferBlendOverrides;
GlShader vert = new GlShader(ShaderType.VERTEX, name + ".vsh", vertex);
GLStateManager.glAttachShader(id, vert.getHandle());
GlShader tessCont = null;
if (tessControl != null) {
tessCont = new GlShader(ShaderType.TESSELATION_CONTROL, name + ".tcs", tessControl);
GLStateManager.glAttachShader(id, tessCont.getHandle());
}
GlShader tessE = null;
if (tessEval != null) {
tessE = new GlShader(ShaderType.TESSELATION_EVAL, name + ".tes", tessEval);
GLStateManager.glAttachShader(id, tessE.getHandle());
}
GlShader geom = null;
if (geometry != null) {
geom = new GlShader(ShaderType.GEOMETRY, name + ".gsh", geometry);
GLStateManager.glAttachShader(id, geom.getHandle());
}
GlShader frag = new GlShader(ShaderType.FRAGMENT, name + ".fsh", fragment);
GLStateManager.glAttachShader(id, frag.getHandle());
GLStateManager.glLinkProgram(this.id);
int status = GLStateManager.glGetProgrami(this.id, GL20.GL_LINK_STATUS);
if (status != 1) {
String message = "Shader link error in Iris DH program! Details: " + GLStateManager.glGetProgramInfoLog(this.id, 9999);
this.free();
throw new RuntimeException(message);
} else {
GLStateManager.glUseProgram(this.id);
}
vert.destroy();
frag.destroy();
if (tessCont != null) tessCont.destroy();
if (tessE != null) tessE.destroy();
if (geom != null) geom.destroy();
blend = override;
ProgramUniforms.Builder uniformBuilder = ProgramUniforms.builder(name, id);
ProgramSamplers.Builder samplerBuilder = ProgramSamplers.builder(id, IrisSamplers.WORLD_RESERVED_TEXTURE_UNITS);
CommonUniforms.addDynamicUniforms(uniformBuilder, FogMode.PER_VERTEX);
customUniforms.assignTo(uniformBuilder);
BuiltinReplacementUniforms.addBuiltinReplacementUniforms(uniformBuilder);
ProgramImages.Builder builder = ProgramImages.builder(id);
pipeline.addGbufferOrShadowSamplers(samplerBuilder, builder,
isShadowPass ? pipeline::getFlippedBeforeShadow : () -> translucent ? pipeline.getFlippedAfterTranslucent() : pipeline.getFlippedAfterPrepare(),
isShadowPass, true, true, false);
customUniforms.mapholderToPass(uniformBuilder, this);
this.uniforms = uniformBuilder.buildUniforms();
this.customUniforms = customUniforms;
samplers = samplerBuilder.build();
images = builder.build();
modelOffsetUniform = tryGetUniformLocation2("modelOffset");
worldYOffsetUniform = tryGetUniformLocation2("worldYOffset");
mircoOffsetUniform = tryGetUniformLocation2("mircoOffset");
projectionUniform = tryGetUniformLocation2("iris_ProjectionMatrix");
projectionInverseUniform = tryGetUniformLocation2("iris_ProjectionMatrixInverse");
modelViewUniform = tryGetUniformLocation2("iris_ModelViewMatrix");
modelViewInverseUniform = tryGetUniformLocation2("iris_ModelViewMatrixInverse");
normalMatrix3fUniform = tryGetUniformLocation2("iris_NormalMatrix");
// Fog/Clip Uniforms
clipDistanceUniform = tryGetUniformLocation2("clipDistance");
}
public static IrisLodRenderProgram createProgram(String name, boolean isShadowPass, boolean translucent, ProgramSource source, CustomUniforms uniforms, DeferredWorldRenderingPipeline pipeline) {
Map<PatchShaderType, String> transformed = TransformPatcher.patchDHTerrain(
name,
source.getVertexSource().orElseThrow(RuntimeException::new),
source.getTessControlSource().orElse(null),
source.getTessEvalSource().orElse(null),
source.getGeometrySource().orElse(null),
source.getFragmentSource().orElseThrow(RuntimeException::new),
pipeline.getTextureMap());
String vertex = transformed.get(PatchShaderType.VERTEX);
String tessControl = transformed.get(PatchShaderType.TESS_CONTROL);
String tessEval = transformed.get(PatchShaderType.TESS_EVAL);
String geometry = transformed.get(PatchShaderType.GEOMETRY);
String fragment = transformed.get(PatchShaderType.FRAGMENT);
PatchedShaderPrinter.debugPatchedShaders(source.getName(), vertex, geometry, tessControl, tessEval, fragment);
List<BufferBlendOverride> bufferOverrides = new ArrayList<>();
source.getDirectives().getBufferBlendOverrides().forEach(information -> {
int index = Ints.indexOf(source.getDirectives().getDrawBuffers(), information.getIndex());
if (index > -1) {
bufferOverrides.add(new BufferBlendOverride(index, information.getBlendMode()));
}
});
return new IrisLodRenderProgram(name, isShadowPass, translucent, source.getDirectives().getBlendModeOverride().orElse(null), bufferOverrides.toArray(BufferBlendOverride[]::new), vertex, tessControl, tessEval, geometry, fragment, uniforms, pipeline);
}
// Noise Uniforms
public int tryGetUniformLocation2(CharSequence name) {
return GLStateManager.glGetUniformLocation(this.id, name);
}
public void setUniform(int index, Matrix4fc matrix) {
if (index == -1 || matrix == null) return;
try (MemoryStack stack = MemoryStack.stackPush()) {
FloatBuffer buffer = stack.callocFloat(16);
matrix.get(buffer);
buffer.rewind();
GLStateManager.glUniformMatrix4(index, false, buffer);
}
}
public void setUniform(int index, Matrix3f matrix) {
if (index == -1) return;
try (MemoryStack stack = MemoryStack.stackPush()) {
FloatBuffer buffer = stack.callocFloat(9);
matrix.get(buffer);
buffer.rewind();
GLStateManager.glUniformMatrix3(index, false, buffer);
}
}
// Override ShaderProgram.bind()
public void bind() {
GLStateManager.glUseProgram(id);
if (blend != null) blend.apply();
for (BufferBlendOverride override : bufferBlendOverrides) {
override.apply();
}
}
public void unbind() {
GLStateManager.glUseProgram(0);
ProgramUniforms.clearActiveUniforms();
ProgramSamplers.clearActiveSamplers();
BlendModeOverride.restore();
}
public void free() {
GLStateManager.glDeleteProgram(id);
}
public void fillUniformData(Matrix4fc projection, Matrix4fc modelView, int worldYOffset, float partialTicks) {
GLStateManager.glUseProgram(id);
GLStateManager.glActiveTexture(GL13.GL_TEXTURE0 + IrisSamplers.LIGHTMAP_TEXTURE_UNIT);
DynamicTexture lightmapTexture = ((EntityRendererAccessor) Minecraft.getMinecraft().entityRenderer).getLightmapTexture();
GLStateManager.glBindTexture(GL11.GL_TEXTURE_2D, lightmapTexture.getGlTextureId());
setUniform(modelViewUniform, modelView);
setUniform(modelViewInverseUniform, modelView.invert(tempMat4a));
setUniform(projectionUniform, projection);
setUniform(projectionInverseUniform, projection.invert(tempMat4b));
setUniform(normalMatrix3fUniform, tempMat4a.set(modelView).invert().transpose3x3(tempMat3));
setUniform(mircoOffsetUniform, 0.01f); // 0.01 block offset
// setUniform(skyLightUniform, skyLight);
if (worldYOffsetUniform != -1) setUniform(worldYOffsetUniform, (float) worldYOffset);
// Fog/Clip Uniforms
float dhNearClipDistance = DhApi.Delayed.renderProxy.getNearClipPlaneDistanceInBlocks(partialTicks);
setUniform(clipDistanceUniform, dhNearClipDistance);
samplers.update();
uniforms.update();
customUniforms.push(this);
images.update();
}
private void setUniform(int index, float value) {
GLStateManager.glUniform1f(index, value);
}
public void setModelPos(DhApiVec3f modelPos) {
setUniform(modelOffsetUniform, modelPos);
}
private void setUniform(int index, DhApiVec3f pos) {
GLStateManager.glUniform3f(index, pos.x, pos.y, pos.z);
}
}
@@ -0,0 +1,383 @@
package net.coderbot.iris.compat.dh;
import com.gtnewhorizons.angelica.glsm.GLStateManager;
import com.gtnewhorizons.angelica.rendering.RenderingState;
import com.seibel.distanthorizons.api.DhApi;
import com.seibel.distanthorizons.api.enums.rendering.EDhApiFogDrawMode;
import com.seibel.distanthorizons.api.enums.rendering.EDhApiRenderPass;
import com.seibel.distanthorizons.api.interfaces.override.IDhApiOverrideable;
import com.seibel.distanthorizons.api.interfaces.override.rendering.IDhApiFramebuffer;
import com.seibel.distanthorizons.api.interfaces.override.rendering.IDhApiGenericObjectShaderProgram;
import com.seibel.distanthorizons.api.interfaces.override.rendering.IDhApiShadowCullingFrustum;
import com.seibel.distanthorizons.api.methods.events.abstractEvents.DhApiAfterDhInitEvent;
import com.seibel.distanthorizons.api.methods.events.abstractEvents.DhApiBeforeApplyShaderRenderEvent;
import com.seibel.distanthorizons.api.methods.events.abstractEvents.DhApiBeforeBufferRenderEvent;
import com.seibel.distanthorizons.api.methods.events.abstractEvents.DhApiBeforeDeferredRenderEvent;
import com.seibel.distanthorizons.api.methods.events.abstractEvents.DhApiBeforeGenericObjectRenderEvent;
import com.seibel.distanthorizons.api.methods.events.abstractEvents.DhApiBeforeGenericRenderSetupEvent;
import com.seibel.distanthorizons.api.methods.events.abstractEvents.DhApiBeforeRenderCleanupEvent;
import com.seibel.distanthorizons.api.methods.events.abstractEvents.DhApiBeforeRenderEvent;
import com.seibel.distanthorizons.api.methods.events.abstractEvents.DhApiBeforeRenderPassEvent;
import com.seibel.distanthorizons.api.methods.events.abstractEvents.DhApiBeforeRenderSetupEvent;
import com.seibel.distanthorizons.api.methods.events.abstractEvents.DhApiBeforeTextureClearEvent;
import com.seibel.distanthorizons.api.methods.events.abstractEvents.DhApiColorDepthTextureCreatedEvent;
import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiCancelableEventParam;
import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiEventParam;
import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiRenderParam;
import com.seibel.distanthorizons.api.objects.math.DhApiVec3f;
import com.seibel.distanthorizons.coreapi.DependencyInjection.OverrideInjector;
import net.coderbot.iris.Iris;
import net.coderbot.iris.pipeline.ShadowRenderer;
import net.coderbot.iris.pipeline.WorldRenderingPipeline;
import net.coderbot.iris.shadows.ShadowRenderingState;
import net.coderbot.iris.uniforms.CapturedRenderingState;
import net.irisshaders.iris.api.v0.IrisApi;
import org.joml.Matrix4f;
import org.lwjgl.opengl.GL11;
public class LodRendererEvents {
// TODO: Query actual world min height for Cubic Chunks compatibility
private static final int WORLD_MIN_Y = 0;
private static boolean eventHandlersBound = false;
private static boolean atTranslucent = false;
private static int textureWidth;
private static int textureHeight;
private static final Matrix4f tempMat4 = new Matrix4f();
// constructor //
public static void setupEventHandlers() {
if (!eventHandlersBound) {
eventHandlersBound = true;
Iris.logger.info("Queuing DH event binding...");
DhApiAfterDhInitEvent beforeCleanupEvent = new DhApiAfterDhInitEvent() {
@Override
public void afterDistantHorizonsInit(DhApiEventParam<Void> event) {
Iris.logger.info("DH Ready, binding Iris event handlers...");
Iris.loadShaderpackWhenPossible();
setupSetDeferredBeforeRenderingEvent();
setupReconnectDepthTextureEvent();
setupGenericEvent();
setupCreateDepthTextureEvent();
setupTransparentRendererEventCancling();
setupBeforeBufferClearEvent();
setupBeforeRenderCleanupEvent();
beforeBufferRenderEvent();
setupBeforeRenderFrameBufferBinding();
setupBeforeRenderPassEvent();
setupBeforeApplyShaderEvent();
DHCompatInternal.dhEnabled = DhApi.Delayed.configs.graphics().renderingEnabled().getValue();
Iris.logger.info("DH Iris events bound.");
}
};
DhApi.events.bind(DhApiAfterDhInitEvent.class, beforeCleanupEvent);
}
}
// setup event handlers //
private static void setupSetDeferredBeforeRenderingEvent() {
DhApiBeforeRenderEvent beforeRenderEvent = new DhApiBeforeRenderEvent() {
// this event is called before DH starts any rendering prep
// canceling it will prevent DH from rendering for that frame
@Override
public void beforeRender(DhApiCancelableEventParam<DhApiRenderParam> event) {
DhApi.Delayed.renderProxy.setDeferTransparentRendering(IrisApi.getInstance().isShaderPackInUse() && getInstance().shouldOverride);
DhApi.Delayed.configs.graphics().fog().drawMode().setValue(getInstance().shouldOverride ? EDhApiFogDrawMode.FOG_DISABLED : EDhApiFogDrawMode.FOG_ENABLED);
}
};
DhApi.events.bind(DhApiBeforeRenderEvent.class, beforeRenderEvent);
}
private static void setupReconnectDepthTextureEvent() {
DhApiBeforeTextureClearEvent beforeRenderEvent = new DhApiBeforeTextureClearEvent() {
@Override
public void beforeClear(DhApiCancelableEventParam<DhApiRenderParam> event) {
var getResult = DhApi.Delayed.renderProxy.getDhDepthTextureId();
if (getResult.success) {
int depthTextureId = getResult.payload;
getInstance().reconnectDHTextures(depthTextureId);
}
}
};
DhApi.events.bind(DhApiBeforeTextureClearEvent.class, beforeRenderEvent);
}
private static void setupGenericEvent() {
DhApiBeforeGenericRenderSetupEvent beforeRenderEvent = new DhApiBeforeGenericRenderSetupEvent() {
@Override
public void beforeSetup(DhApiEventParam<DhApiRenderParam> dhApiEventParam) {
if (getInstance().getGenericFB() != null) {
getInstance().getGenericFB().bind();
}
}
};
DhApiBeforeGenericObjectRenderEvent beforeDrawEvent = new DhApiBeforeGenericObjectRenderEvent() {
@Override
public void beforeRender(DhApiCancelableEventParam<EventParam> dhApiCancelableEventParam) {
if (dhApiCancelableEventParam.value.resourceLocationPath.equalsIgnoreCase("Clouds")) {
if (getInstance().avoidRenderingClouds()) {
dhApiCancelableEventParam.cancelEvent();
}
}
}
};
DhApi.events.bind(DhApiBeforeGenericRenderSetupEvent.class, beforeRenderEvent);
DhApi.events.bind(DhApiBeforeGenericObjectRenderEvent.class, beforeDrawEvent);
}
private static DHCompatInternal getInstance() {
return Iris.getPipelineManager().getPipeline().map(WorldRenderingPipeline::getDHCompat).map(DHCompat::getInstance).orElse(DHCompatInternal.SHADERLESS);
}
private static void setupCreateDepthTextureEvent() {
DhApiColorDepthTextureCreatedEvent beforeRenderEvent = new DhApiColorDepthTextureCreatedEvent() {
@Override
public void onResize(DhApiEventParam<EventParam> input) {
textureWidth = input.value.newWidth;
textureHeight = input.value.newHeight;
}
};
DhApi.events.bind(DhApiColorDepthTextureCreatedEvent.class, beforeRenderEvent);
}
private static void setupTransparentRendererEventCancling() {
DhApiBeforeRenderEvent beforeRenderEvent = new DhApiBeforeRenderEvent() {
@Override
public void beforeRender(DhApiCancelableEventParam<DhApiRenderParam> event) {
if (ShadowRenderingState.areShadowsCurrentlyBeingRendered() && (!getInstance().shouldOverrideShadow)) {
event.cancelEvent();
}
}
};
DhApiBeforeDeferredRenderEvent beforeRenderEvent2 = new DhApiBeforeDeferredRenderEvent() {
@Override
public void beforeRender(DhApiCancelableEventParam<DhApiRenderParam> event) {
if (ShadowRenderingState.areShadowsCurrentlyBeingRendered() && (!getInstance().shouldOverrideShadow)) {
event.cancelEvent();
}
}
};
DhApi.events.bind(DhApiBeforeRenderEvent.class, beforeRenderEvent);
DhApi.events.bind(DhApiBeforeDeferredRenderEvent.class, beforeRenderEvent2);
}
private static void setupBeforeRenderCleanupEvent() {
DhApiBeforeRenderCleanupEvent beforeCleanupEvent = new DhApiBeforeRenderCleanupEvent() {
@Override
public void beforeCleanup(DhApiEventParam<DhApiRenderParam> event) {
if (getInstance().shouldOverride) {
if (ShadowRenderingState.areShadowsCurrentlyBeingRendered()) {
getInstance().getShadowShader().unbind();
} else {
getInstance().getSolidShader().unbind();
if (atTranslucent) {
GLStateManager.enableCull();
}
}
}
}
};
DhApi.events.bind(DhApiBeforeRenderCleanupEvent.class, beforeCleanupEvent);
}
private static void setupBeforeBufferClearEvent() {
DhApiBeforeTextureClearEvent beforeCleanupEvent = new DhApiBeforeTextureClearEvent() {
@Override
public void beforeClear(DhApiCancelableEventParam<DhApiRenderParam> event) {
if (event.value.renderPass == EDhApiRenderPass.OPAQUE) {
if (ShadowRenderingState.areShadowsCurrentlyBeingRendered()) {
event.cancelEvent();
} else if (getInstance().shouldOverride) {
GLStateManager.glClear(GL11.GL_DEPTH_BUFFER_BIT);
event.cancelEvent();
}
}
}
};
DhApi.events.bind(DhApiBeforeTextureClearEvent.class, beforeCleanupEvent);
}
private static void beforeBufferRenderEvent() {
DhApiBeforeBufferRenderEvent beforeCleanupEvent = new DhApiBeforeBufferRenderEvent() {
@Override
public void beforeRender(DhApiEventParam<EventParam> input) {
DHCompatInternal instance = getInstance();
if (instance.shouldOverride) {
DhApiVec3f modelPos = input.value.modelPos;
if (ShadowRenderingState.areShadowsCurrentlyBeingRendered()) {
instance.getShadowShader().bind();
instance.getShadowShader().setModelPos(modelPos);
} else if (atTranslucent) {
instance.getTranslucentShader().bind();
instance.getTranslucentShader().setModelPos(modelPos);
} else {
instance.getSolidShader().bind();
instance.getSolidShader().setModelPos(modelPos);
}
}
}
};
DhApi.events.bind(DhApiBeforeBufferRenderEvent.class, beforeCleanupEvent);
}
private static void setupBeforeRenderFrameBufferBinding() {
DhApiBeforeRenderSetupEvent beforeRenderPassEvent = new DhApiBeforeRenderSetupEvent() {
@Override
public void beforeSetup(DhApiEventParam<DhApiRenderParam> event) {
DHCompatInternal instance = getInstance();
OverrideInjector.INSTANCE.unbind(IDhApiShadowCullingFrustum.class, (IDhApiOverrideable) ShadowRenderer.FRUSTUM);
OverrideInjector.INSTANCE.unbind(IDhApiFramebuffer.class, instance.getShadowFBWrapper());
OverrideInjector.INSTANCE.unbind(IDhApiFramebuffer.class, instance.getSolidFBWrapper());
OverrideInjector.INSTANCE.unbind(IDhApiGenericObjectShaderProgram.class, instance.getGenericShader());
if (instance.shouldOverride) {
if (instance.getGenericShader() != null) {
OverrideInjector.INSTANCE.bind(IDhApiGenericObjectShaderProgram.class, instance.getGenericShader());
}
if (ShadowRenderingState.areShadowsCurrentlyBeingRendered() && instance.shouldOverrideShadow) {
OverrideInjector.INSTANCE.bind(IDhApiFramebuffer.class, instance.getShadowFBWrapper());
OverrideInjector.INSTANCE.bind(IDhApiShadowCullingFrustum.class, (IDhApiOverrideable) ShadowRenderer.FRUSTUM);
} else {
OverrideInjector.INSTANCE.bind(IDhApiFramebuffer.class, instance.getSolidFBWrapper());
}
}
}
};
DhApi.events.bind(DhApiBeforeRenderSetupEvent.class, beforeRenderPassEvent);
}
private static void setupBeforeRenderPassEvent() {
DhApiBeforeRenderPassEvent beforeCleanupEvent = new DhApiBeforeRenderPassEvent() {
@Override
public void beforeRender(DhApiEventParam<DhApiRenderParam> event) {
DHCompatInternal instance = getInstance();
// config overrides
if (instance.shouldOverride) {
DhApi.Delayed.configs.graphics().ambientOcclusion().enabled().setValue(false);
DhApi.Delayed.configs.graphics().fog().drawMode().setValue(EDhApiFogDrawMode.FOG_DISABLED);
if (event.value.renderPass == EDhApiRenderPass.OPAQUE_AND_TRANSPARENT) {
Iris.logger.error("Unexpected; somehow the Opaque + Translucent pass ran with shaders on.");
}
} else {
DhApi.Delayed.configs.graphics().ambientOcclusion().enabled().clearValue();
DhApi.Delayed.configs.graphics().fog().drawMode().clearValue();
}
// cleanup
if (event.value.renderPass == EDhApiRenderPass.OPAQUE) {
if (instance.shouldOverride) {
if (ShadowRenderingState.areShadowsCurrentlyBeingRendered()) {
instance.getShadowShader().bind();
} else {
instance.getSolidShader().bind();
}
atTranslucent = false;
}
}
// opaque
if (event.value.renderPass == EDhApiRenderPass.OPAQUE) {
float partialTicks = event.value.partialTicks;
if (instance.shouldOverride) {
if (ShadowRenderingState.areShadowsCurrentlyBeingRendered()) {
instance.getShadowShader().fillUniformData(
ShadowRenderer.PROJECTION, ShadowRenderer.MODELVIEW,
WORLD_MIN_Y,
partialTicks);
} else {
Matrix4f projection = RenderingState.INSTANCE.getProjectionMatrix();;
instance.getSolidShader().fillUniformData(
tempMat4.setPerspective(projection.perspectiveFov(), projection.m11() / projection.m00(), event.value.nearClipPlane, event.value.farClipPlane),
RenderingState.INSTANCE.getModelViewMatrix(),
WORLD_MIN_Y,
partialTicks);
}
}
}
// transparent
if (event.value.renderPass == EDhApiRenderPass.TRANSPARENT) {
float partialTicks = event.value.partialTicks;
int depthTextureId = DhApi.Delayed.renderProxy.getDhDepthTextureId().payload;
if (instance.shouldOverrideShadow && ShadowRenderingState.areShadowsCurrentlyBeingRendered()) {
instance.getShadowShader().bind();
instance.getShadowFB().bind();
atTranslucent = true;
return;
}
if (instance.shouldOverride && instance.getTranslucentFB() != null) {
instance.copyTranslucents(textureWidth, textureHeight);
instance.getTranslucentShader().bind();
Matrix4f projection = RenderingState.INSTANCE.getProjectionMatrix();
GLStateManager.disableCull();
instance.getTranslucentShader().fillUniformData(
new Matrix4f().setPerspective(projection.perspectiveFov(), projection.m11() / projection.m00(), event.value.nearClipPlane, event.value.farClipPlane),
RenderingState.INSTANCE.getModelViewMatrix(),
WORLD_MIN_Y,
partialTicks);
instance.getTranslucentFB().bind();
}
atTranslucent = true;
}
}
};
DhApi.events.bind(DhApiBeforeRenderPassEvent.class, beforeCleanupEvent);
}
private static void setupBeforeApplyShaderEvent() {
DhApiBeforeApplyShaderRenderEvent beforeApplyShaderEvent = new DhApiBeforeApplyShaderRenderEvent() {
@Override
public void beforeRender(DhApiCancelableEventParam<DhApiRenderParam> event) {
if (IrisApi.getInstance().isShaderPackInUse()) {
DHCompatInternal instance = getInstance();
OverrideInjector.INSTANCE.unbind(IDhApiShadowCullingFrustum.class, (IDhApiOverrideable) ShadowRenderer.FRUSTUM);
OverrideInjector.INSTANCE.unbind(IDhApiFramebuffer.class, instance.getShadowFBWrapper());
OverrideInjector.INSTANCE.unbind(IDhApiFramebuffer.class, instance.getSolidFBWrapper());
event.cancelEvent();
}
}
};
DhApi.events.bind(DhApiBeforeApplyShaderRenderEvent.class, beforeApplyShaderEvent);
}
}
@@ -33,12 +33,18 @@ public class IrisConfig {
*/
private boolean disableUpdateMessage;
/**
* If debug features should be enabled. Gives much more detailed OpenGL error outputs at the cost of performance.
*/
private boolean enableDebugOptions;
private final Path propertiesPath;
public IrisConfig(Path propertiesPath) {
shaderPackName = null;
enableShaders = true;
disableUpdateMessage = false;
enableDebugOptions = false;
this.propertiesPath = propertiesPath;
}
@@ -103,6 +109,10 @@ public class IrisConfig {
this.enableShaders = enabled;
}
public boolean areDebugOptionsEnabled() {
return enableDebugOptions;
}
/**
* loads the config file and then populates the string, int, and boolean entries with the parsed entries
*
@@ -121,6 +131,7 @@ public class IrisConfig {
}
shaderPackName = properties.getProperty("shaderPack");
enableShaders = !"false".equals(properties.getProperty("enableShaders"));
enableDebugOptions = "true".equals(properties.getProperty("enableDebugOptions"));
disableUpdateMessage = "true".equals(properties.getProperty("disableUpdateMessage"));
// TODO: GUI
try {
@@ -147,6 +158,7 @@ public class IrisConfig {
final Properties properties = new Properties();
properties.setProperty("shaderPack", getShaderPackName().orElse(""));
properties.setProperty("enableShaders", enableShaders ? "true" : "false");
properties.setProperty("enableDebugOptions", enableDebugOptions ? "true" : "false");
properties.setProperty("disableUpdateMessage", disableUpdateMessage ? "true" : "false");
properties.setProperty("maxShadowRenderDistance", String.valueOf(IrisVideoSettings.shadowDistance));
// NB: This uses ISO-8859-1 with unicode escapes as the encoding
@@ -8,6 +8,7 @@ public enum RenderCondition {
CLOUDS,
DESTROY,
BLOCK_ENTITIES,
BLOCK_ENTITIES_TRANSLUCENT,
BEACON_BEAM,
ENTITIES,
ENTITIES_TRANSLUCENT,
@@ -45,6 +45,12 @@ public class GlFramebuffer extends GlResource {
this.hasDepthAttachment = true;
}
public void addDepthAttachmentBypass(int texture) {
final int fb = getGlId();
RenderSystem.framebufferTexture2D(fb, GL30.GL_FRAMEBUFFER, GL30.GL_DEPTH_ATTACHMENT, GL11.GL_TEXTURE_2D, texture, 0);
this.hasDepthAttachment = true;
}
public void addColorAttachment(int index, int texture) {
final int fb = getGlId();
@@ -2,6 +2,7 @@ package net.coderbot.iris.gl.program;
import com.google.common.collect.ImmutableList;
import com.gtnewhorizons.angelica.config.AngelicaConfig;
import com.gtnewhorizons.angelica.glsm.GLStateManager;
import com.gtnewhorizons.angelica.glsm.RenderSystem;
import java.nio.IntBuffer;
import java.util.ArrayList;
@@ -189,7 +190,7 @@ public class ProgramUniforms {
public ProgramUniforms buildUniforms() {
// Check for any unsupported uniforms and warn about them so that we can easily figure out what uniforms we need to add.
final int activeUniforms = GL20.glGetProgrami(program, GL20.GL_ACTIVE_UNIFORMS);
final int activeUniforms = GLStateManager.glGetProgrami(program, GL20.GL_ACTIVE_UNIFORMS);
IntBuffer sizeType = BufferUtils.createIntBuffer(2);
for (int index = 0; index < activeUniforms; index++) {
@@ -4,6 +4,7 @@ import com.google.common.collect.ImmutableList;
import com.gtnewhorizons.angelica.Tags;
import com.gtnewhorizons.angelica.config.AngelicaConfig;
import cpw.mods.fml.common.Loader;
import net.coderbot.iris.compat.dh.DHCompat;
import net.coderbot.iris.parsing.BiomeCategories;
import net.coderbot.iris.pipeline.HandRenderer;
import net.coderbot.iris.pipeline.WorldRenderingPhase;
@@ -77,10 +78,32 @@ public class StandardMacros {
define(standardDefines, "MC_SPECULAR_MAP");
define(standardDefines, "MC_RENDER_QUALITY", "1.0");
define(standardDefines, "MC_SHADOW_QUALITY", "1.0");
define(standardDefines, "IS_ANGELICA");
if (AngelicaConfig.defineIsIris) {
define(standardDefines, "IS_IRIS");
}
define(standardDefines, "IS_ANGELICA");
if (AngelicaConfig.defineIsIris) {
define(standardDefines, "IS_IRIS");
}
if (DHCompat.hasRenderingEnabled()) {
define(standardDefines, "DISTANT_HORIZONS");
}
define(standardDefines, "DH_BLOCK_UNKNOWN", String.valueOf(0));
define(standardDefines, "DH_BLOCK_LEAVES", String.valueOf(1));
define(standardDefines, "DH_BLOCK_STONE", String.valueOf(2));
define(standardDefines, "DH_BLOCK_WOOD", String.valueOf(3));
define(standardDefines, "DH_BLOCK_METAL", String.valueOf(4));
define(standardDefines, "DH_BLOCK_DIRT", String.valueOf(5));
define(standardDefines, "DH_BLOCK_LAVA", String.valueOf(6));
define(standardDefines, "DH_BLOCK_DEEPSLATE", String.valueOf(7));
define(standardDefines, "DH_BLOCK_SNOW", String.valueOf(8));
define(standardDefines, "DH_BLOCK_SAND", String.valueOf(9));
define(standardDefines, "DH_BLOCK_TERRACOTTA", String.valueOf(10));
define(standardDefines, "DH_BLOCK_NETHER_STONE", String.valueOf(11));
define(standardDefines, "DH_BLOCK_WATER", String.valueOf(12));
define(standardDefines, "DH_BLOCK_GRASS", String.valueOf(13));
define(standardDefines, "DH_BLOCK_AIR", String.valueOf(14));
define(standardDefines, "DH_BLOCK_ILLUMINATED", String.valueOf(15));
define(standardDefines, "ANGELICA_VERSION", makeAngelicaVersion());
define(standardDefines, "MC_HAND_DEPTH", Float.toString(HandRenderer.DEPTH));
@@ -3,6 +3,7 @@ package net.coderbot.iris.gl.uniform;
import net.coderbot.iris.gl.state.ValueUpdateNotifier;
import org.joml.Vector2i;
import org.joml.Vector3i;
import org.joml.Vector3ic;
import org.joml.Vector4f;
import org.joml.Vector4i;
@@ -43,7 +44,7 @@ public interface DynamicLocationalUniformHolder extends LocationalUniformHolder,
return this;
}
default DynamicUniformHolder uniform3i(String name, Supplier<Vector3i> value, ValueUpdateNotifier notifier) {
default DynamicUniformHolder uniform3i(String name, Supplier<Vector3ic> value, ValueUpdateNotifier notifier) {
location(name, UniformType.VEC3I).ifPresent(id -> addDynamicUniform(new Vector3IntegerJomlUniform(id, value, notifier), notifier));
return this;
@@ -3,6 +3,7 @@ package net.coderbot.iris.gl.uniform;
import net.coderbot.iris.gl.state.ValueUpdateNotifier;
import org.joml.Vector2i;
import org.joml.Vector3i;
import org.joml.Vector3ic;
import org.joml.Vector4f;
import org.joml.Vector4i;
@@ -16,7 +17,7 @@ public interface DynamicUniformHolder extends UniformHolder {
DynamicUniformHolder uniform1f(String name, DoubleSupplier value, ValueUpdateNotifier notifier);
DynamicUniformHolder uniform1i(String name, IntSupplier value, ValueUpdateNotifier notifier);
DynamicUniformHolder uniform2i(String name, Supplier<Vector2i> value, ValueUpdateNotifier notifier);
DynamicUniformHolder uniform3i(String name, Supplier<Vector3i> value, ValueUpdateNotifier notifier);
DynamicUniformHolder uniform3i(String name, Supplier<Vector3ic> value, ValueUpdateNotifier notifier);
DynamicUniformHolder uniform4f(String name, Supplier<Vector4f> value, ValueUpdateNotifier notifier);
DynamicUniformHolder uniform4fArray(String name, Supplier<float[]> value, ValueUpdateNotifier notifier);
DynamicUniformHolder uniform4i(String name, Supplier<Vector4i> value, ValueUpdateNotifier notifier);
@@ -2,11 +2,14 @@ package net.coderbot.iris.gl.uniform;
import net.minecraft.util.Vec3;
import org.joml.Matrix4f;
import org.joml.Matrix4fc;
import org.joml.Vector2f;
import org.joml.Vector2i;
import org.joml.Vector3d;
import org.joml.Vector3f;
import org.joml.Vector3fc;
import org.joml.Vector3i;
import org.joml.Vector3ic;
import org.joml.Vector4f;
import java.util.OptionalInt;
@@ -70,14 +73,14 @@ public interface LocationalUniformHolder extends UniformHolder {
}
@Override
default LocationalUniformHolder uniform3f(UniformUpdateFrequency updateFrequency, String name, Supplier<Vector3f> value) {
default LocationalUniformHolder uniform3f(UniformUpdateFrequency updateFrequency, String name, Supplier<Vector3fc> value) {
location(name, UniformType.VEC3).ifPresent(id -> addUniform(updateFrequency, new Vector3Uniform(id, value)));
return this;
}
@Override
default LocationalUniformHolder uniform3i(UniformUpdateFrequency updateFrequency, String name, Supplier<Vector3i> value) {
default LocationalUniformHolder uniform3i(UniformUpdateFrequency updateFrequency, String name, Supplier<Vector3ic> value) {
location(name, UniformType.VEC3I).ifPresent(id -> addUniform(updateFrequency, new Vector3IntegerJomlUniform(id, value)));
return this;
@@ -119,7 +122,7 @@ public interface LocationalUniformHolder extends UniformHolder {
}
@Override
default LocationalUniformHolder uniformMatrix(UniformUpdateFrequency updateFrequency, String name, Supplier<Matrix4f> value) {
default LocationalUniformHolder uniformMatrix(UniformUpdateFrequency updateFrequency, String name, Supplier<Matrix4fc> value) {
location(name, UniformType.MAT4).ifPresent(id -> addUniform(updateFrequency, new MatrixUniform(id, value)));
return this;
@@ -2,6 +2,7 @@ package net.coderbot.iris.gl.uniform;
import com.gtnewhorizons.angelica.glsm.RenderSystem;
import org.joml.Matrix4f;
import org.joml.Matrix4fc;
import org.lwjgl.BufferUtils;
import java.nio.FloatBuffer;
@@ -10,9 +11,9 @@ import java.util.function.Supplier;
public class MatrixUniform extends Uniform {
private final FloatBuffer buffer = BufferUtils.createFloatBuffer(16);
private Matrix4f cachedValue;
private final Supplier<Matrix4f> value;
private final Supplier<Matrix4fc> value;
MatrixUniform(int location, Supplier<Matrix4f> value) {
MatrixUniform(int location, Supplier<Matrix4fc> value) {
super(location);
this.cachedValue = null;
@@ -21,7 +22,7 @@ public class MatrixUniform extends Uniform {
@Override
public void update() {
final Matrix4f newValue = value.get();
final Matrix4fc newValue = value.get();
if( newValue == null ){
throw new RuntimeException("MatrixUniform value is null");
}
@@ -1,12 +1,13 @@
package net.coderbot.iris.gl.uniform;
import net.minecraft.util.Vec3;
import org.joml.Matrix4f;
import org.joml.Matrix4fc;
import org.joml.Vector2f;
import org.joml.Vector2i;
import org.joml.Vector3d;
import org.joml.Vector3f;
import org.joml.Vector3fc;
import org.joml.Vector3i;
import org.joml.Vector3ic;
import org.joml.Vector4f;
import java.util.function.BooleanSupplier;
@@ -29,9 +30,9 @@ public interface UniformHolder {
UniformHolder uniform2i(UniformUpdateFrequency updateFrequency, String name, Supplier<Vector2i> value);
UniformHolder uniform3f(UniformUpdateFrequency updateFrequency, String name, Supplier<Vector3f> value);
UniformHolder uniform3f(UniformUpdateFrequency updateFrequency, String name, Supplier<Vector3fc> value);
UniformHolder uniform3i(UniformUpdateFrequency updateFrequency, String name, Supplier<Vector3i> value);
UniformHolder uniform3i(UniformUpdateFrequency updateFrequency, String name, Supplier<Vector3ic> value);
UniformHolder uniformVanilla3f(UniformUpdateFrequency updateFrequency, String name, Supplier<Vec3> value);
@@ -43,7 +44,7 @@ public interface UniformHolder {
UniformHolder uniform4fArray(UniformUpdateFrequency updateFrequency, String name, Supplier<float[]> value);
UniformHolder uniformMatrix(UniformUpdateFrequency updateFrequency, String name, Supplier<Matrix4f> value);
UniformHolder uniformMatrix(UniformUpdateFrequency updateFrequency, String name, Supplier<Matrix4fc> value);
UniformHolder uniformMatrixFromArray(UniformUpdateFrequency updateFrequency, String name, Supplier<float[]> value);
@@ -3,21 +3,22 @@ package net.coderbot.iris.gl.uniform;
import com.gtnewhorizons.angelica.glsm.RenderSystem;
import net.coderbot.iris.gl.state.ValueUpdateNotifier;
import org.joml.Vector3i;
import org.joml.Vector3ic;
import java.util.function.Supplier;
public class Vector3IntegerJomlUniform extends Uniform {
private Vector3i cachedValue;
private final Supplier<Vector3i> value;
private final Vector3i cachedValue;
private final Supplier<Vector3ic> value;
Vector3IntegerJomlUniform(int location, Supplier<Vector3i> value) {
Vector3IntegerJomlUniform(int location, Supplier<Vector3ic> value) {
this(location, value, null);
}
Vector3IntegerJomlUniform(int location, Supplier<Vector3i> value, ValueUpdateNotifier notifier) {
Vector3IntegerJomlUniform(int location, Supplier<Vector3ic> value, ValueUpdateNotifier notifier) {
super(location, notifier);
this.cachedValue = null;
this.cachedValue = new Vector3i();
this.value = value;
}
@@ -31,11 +32,11 @@ public class Vector3IntegerJomlUniform extends Uniform {
}
private void updateValue() {
Vector3i newValue = value.get();
Vector3ic newValue = value.get();
if (cachedValue == null || !newValue.equals(cachedValue)) {
cachedValue = newValue;
RenderSystem.uniform3i(this.location, newValue.x, newValue.y, newValue.z);
if (!newValue.equals(cachedValue)) {
cachedValue.set(newValue.x(), newValue.y(), newValue.z());
RenderSystem.uniform3i(this.location, cachedValue.x(), cachedValue.y(), cachedValue.z());
}
}
}
@@ -3,15 +3,16 @@ package net.coderbot.iris.gl.uniform;
import com.gtnewhorizons.angelica.glsm.RenderSystem;
import org.joml.Vector3d;
import org.joml.Vector3f;
import org.joml.Vector3fc;
import org.joml.Vector4f;
import java.util.function.Supplier;
public class Vector3Uniform extends Uniform {
private final Vector3f cachedValue;
private final Supplier<Vector3f> value;
private final Supplier<Vector3fc> value;
Vector3Uniform(int location, Supplier<Vector3f> value) {
Vector3Uniform(int location, Supplier<Vector3fc> value) {
super(location);
this.cachedValue = new Vector3f();
@@ -44,7 +45,7 @@ public class Vector3Uniform extends Uniform {
@Override
public void update() {
Vector3f newValue = value.get();
Vector3fc newValue = value.get();
if (!newValue.equals(cachedValue)) {
cachedValue.set(newValue.x(), newValue.y(), newValue.z());
@@ -8,6 +8,7 @@ import net.coderbot.iris.shaderpack.option.OptionSet;
import net.coderbot.iris.shaderpack.option.Profile;
import net.coderbot.iris.shaderpack.option.ProfileSet;
import net.coderbot.iris.shaderpack.option.menu.OptionMenuProfileElement;
import net.coderbot.iris.shaderpack.option.menu.ProfileElementTracker;
import net.coderbot.iris.shaderpack.option.values.OptionValues;
import net.minecraft.client.Minecraft;
import net.minecraft.client.resources.I18n;
@@ -30,6 +31,7 @@ public class ProfileElementWidget extends BaseOptionElementWidget<OptionMenuProf
public void init(ShaderPackScreen screen, NavigationController navigation) {
super.init(screen, navigation);
this.setLabel(PROFILE_LABEL);
boolean secondProfileSet = ProfileElementTracker.isSecondProfileSet(this.element);
final ProfileSet profiles = this.element.profiles;
final OptionSet options = this.element.options;
@@ -41,7 +43,8 @@ public class ProfileElementWidget extends BaseOptionElementWidget<OptionMenuProf
this.previous = result.previous;
final Optional<String> profileName = result.current.map(p -> p.name);
this.profileLabel = profileName.map(name -> GuiUtil.translateOrDefault(name, "profile." + name)).orElse(PROFILE_CUSTOM);
String translationKey = "profile" + (secondProfileSet ? "2." : ".") + profileName.orElse("custom");
this.profileLabel = profileName.map(name -> GuiUtil.translateOrDefault(name, translationKey)).orElse(PROFILE_CUSTOM);
}
@Override
@@ -63,7 +66,7 @@ public class ProfileElementWidget extends BaseOptionElementWidget<OptionMenuProf
@Override
public String getCommentKey() {
return "profile.comment";
return ProfileElementTracker.isSecondProfileSet(this.element) ? "profile2.comment" : "profile.comment";
}
@Override
@@ -1,7 +1,7 @@
package net.coderbot.iris.gui.screen;
import com.gtnewhorizons.angelica.AngelicaMod;
import com.gtnewhorizons.angelica.glsm.GLStateManager;
import com.gtnewhorizons.angelica.loading.AngelicaTweaker;
import net.coderbot.iris.Iris;
import net.coderbot.iris.gui.GuiUtil;
import net.coderbot.iris.gui.NavigationController;
@@ -460,7 +460,7 @@ public class ShaderPackScreen extends GuiScreen implements HudHideable {
}
if (openViaSystemClass) {
AngelicaTweaker.LOGGER.debug("Opening via system class!");
AngelicaMod.LOGGER.debug("Opening via system class!");
Sys.openURL("file://" + uri);
}
}
@@ -29,12 +29,14 @@ import net.coderbot.iris.gl.buffer.ShaderStorageBufferHolder;
import net.coderbot.iris.gl.buffer.ShaderStorageInfo;
import net.coderbot.iris.gl.framebuffer.GlFramebuffer;
import net.coderbot.iris.gl.image.GlImage;
import net.coderbot.iris.gl.image.ImageHolder;
import net.coderbot.iris.gl.image.ImageInformation;
import net.coderbot.iris.gl.program.ComputeProgram;
import net.coderbot.iris.gl.program.Program;
import net.coderbot.iris.gl.program.ProgramBuilder;
import net.coderbot.iris.gl.program.ProgramImages;
import net.coderbot.iris.gl.program.ProgramSamplers;
import net.coderbot.iris.gl.sampler.SamplerHolder;
import net.coderbot.iris.gl.state.FogMode;
import net.coderbot.iris.gl.texture.DepthBufferFormat;
import net.coderbot.iris.gl.texture.TextureType;
@@ -45,6 +47,7 @@ import net.coderbot.iris.postprocess.BufferFlipper;
import net.coderbot.iris.postprocess.CenterDepthSampler;
import net.coderbot.iris.postprocess.CompositeRenderer;
import net.coderbot.iris.postprocess.FinalPassRenderer;
import net.coderbot.iris.postprocess.FullScreenQuadRenderer;
import net.coderbot.iris.postprocess.ProgramBuildContext;
import net.coderbot.iris.rendertarget.IRenderTargetExt;
import net.coderbot.iris.rendertarget.NativeImageBackedSingleColorTexture;
@@ -176,6 +179,7 @@ public class DeferredWorldRenderingPipeline implements WorldRenderingPipeline, R
private final boolean oldLighting;
private final boolean allowConcurrentCompute;
private final OptionalInt forcedShadowRenderDistanceChunks;
private final CloudSetting dhCloudSetting;
private Pass current = null;
@@ -191,6 +195,7 @@ public class DeferredWorldRenderingPipeline implements WorldRenderingPipeline, R
private int currentSpecularTexture;
private PackDirectives packDirectives;
private final Set<FeatureFlags> activeFeatures;
private final ProgramFallbackResolver resolver;
public DeferredWorldRenderingPipeline(ProgramSet programs) {
Objects.requireNonNull(programs);
@@ -205,7 +210,7 @@ public class DeferredWorldRenderingPipeline implements WorldRenderingPipeline, R
.map(DeferredWorldRenderingPipeline::submitCompositeTransform)
.orElse(null);
final ProgramFallbackResolver resolver = new ProgramFallbackResolver(programs);
resolver = new ProgramFallbackResolver(programs);
final Map<Pair<String, InputAvailability>, CompletableFuture<Map<PatchShaderType, String>>> attributeTransformFutures = submitAttributeTransforms(resolver);
final Optional<ProgramSource> terrainSource = first(programs.getGbuffersTerrain(), programs.getGbuffersTexturedLit(), programs.getGbuffersTextured(), programs.getGbuffersBasic());
@@ -227,6 +232,7 @@ public class DeferredWorldRenderingPipeline implements WorldRenderingPipeline, R
this.shouldRenderWeather = programs.getPackDirectives().shouldRenderWeather();
this.shouldRenderWeatherParticles = programs.getPackDirectives().shouldRenderWeatherParticles();
this.shouldWriteRainAndSnowToDepthBuffer = programs.getPackDirectives().rainDepth();
this.dhCloudSetting = programs.getPackDirectives().getDHCloudSetting();
this.shouldRenderParticlesBeforeDeferred = programs.getPackDirectives().getParticleRenderingSettings()
.map(s -> s == net.coderbot.iris.shaderpack.ParticleRenderingSettings.BEFORE || s == net.coderbot.iris.shaderpack.ParticleRenderingSettings.MIXED)
.orElse(false);
@@ -367,6 +373,7 @@ public class DeferredWorldRenderingPipeline implements WorldRenderingPipeline, R
null, ProgramId.Clouds, ProgramId.Clouds,
null, ProgramId.DamagedBlock, ProgramId.DamagedBlock,
ProgramId.Block, ProgramId.Block, ProgramId.Block,
ProgramId.BlockTrans, ProgramId.BlockTrans, ProgramId.BlockTrans,
ProgramId.BeaconBeam, ProgramId.BeaconBeam, ProgramId.BeaconBeam,
ProgramId.Entities, ProgramId.Entities, ProgramId.Entities,
ProgramId.EntitiesTrans, ProgramId.EntitiesTrans, ProgramId.EntitiesTrans,
@@ -585,7 +592,7 @@ public class DeferredWorldRenderingPipeline implements WorldRenderingPipeline, R
renderTargets, flippedAfterPrepare, flippedAfterTranslucent,
celeritasShadowFb);
this.dhCompat = new DHCompat();
this.dhCompat = new DHCompat(this, shadowDirectives.isDhShadowEnabled().orElse(true));
}
private RenderTargets getRenderTargets() {
@@ -719,6 +726,10 @@ public class DeferredWorldRenderingPipeline implements WorldRenderingPipeline, R
return RenderCondition.ENTITIES;
}
case BLOCK_ENTITIES:
if (GLStateManager.getBlendState().getSrcRgb() == SRC_ALPHA &&
GLStateManager.getBlendState().getDstRgb() == ONE_MINUS_SRC_ALPHA) {
return RenderCondition.BLOCK_ENTITIES_TRANSLUCENT;
}
return RenderCondition.BLOCK_ENTITIES;
case DESTROY:
return RenderCondition.DESTROY;
@@ -749,6 +760,13 @@ public class DeferredWorldRenderingPipeline implements WorldRenderingPipeline, R
return p != null ? p.getProgramId() : -1;
}
/**
* Called when a mod overrides the GL program away from the active Iris pass
*/
public void onModProgramOverride() {
current = null;
}
private void matchPass() {
if (!isRenderingWorld || isRenderingFullScreenPass || isPostChain || !isMainBound) {
return;
@@ -883,7 +901,8 @@ public class DeferredWorldRenderingPipeline implements WorldRenderingPipeline, R
builder.bindAttributeLocation(13, "at_tangent");
builder.bindAttributeLocation(14, "at_midBlock");
AlphaTestOverride alphaTestOverride = programDirectives.getAlphaTestOverride().orElse(null);
AlphaTestOverride alphaTestOverride = programDirectives.getAlphaTestOverride()
.orElse(id.getDefaultAlphaTestOverride());
List<BufferBlendOverride> bufferOverrides = new ArrayList<>();
@@ -902,6 +921,38 @@ public class DeferredWorldRenderingPipeline implements WorldRenderingPipeline, R
return pass;
}
public void addGbufferOrShadowSamplers(SamplerHolder samplers, ImageHolder images, Supplier<ImmutableSet<Integer>> flipped,
boolean isShadowPass, boolean hasTexture, boolean hasLightmap, boolean hasOverlay) {
TextureStage textureStage = TextureStage.GBUFFERS_AND_SHADOW;
ProgramSamplers.CustomTextureSamplerInterceptor customTextureSamplerInterceptor =
ProgramSamplers.customTextureSamplerInterceptor(samplers, customTextureManager.getCustomTextureIdMap(textureStage));
IrisSamplers.addRenderTargetSamplers(customTextureSamplerInterceptor, flipped, renderTargets, false, this);
IrisImages.addRenderTargetImages(images, flipped, renderTargets);
if (!shouldBindPBR) {
shouldBindPBR = IrisSamplers.hasPBRSamplers(customTextureSamplerInterceptor);
}
IrisSamplers.addLevelSamplers(customTextureSamplerInterceptor, this, whitePixel, new InputAvailability(hasTexture, hasLightmap));
if (!isShadowPass) {
IrisSamplers.addWorldDepthSamplers(customTextureSamplerInterceptor, renderTargets);
}
IrisSamplers.addNoiseSampler(customTextureSamplerInterceptor, customTextureManager.getNoiseTexture());
IrisSamplers.addCustomImages(customTextureSamplerInterceptor, customImages);
IrisSamplers.addCustomTextures(customTextureSamplerInterceptor, customTextureManager.getIrisCustomTextures());
IrisImages.addCustomImages(images, customImages);
if (IrisSamplers.hasShadowSamplers(customTextureSamplerInterceptor)) {
IrisSamplers.addShadowSamplers(customTextureSamplerInterceptor, shadowTargetsSupplier.get(), null, true);
}
if (isShadowPass || IrisImages.hasShadowImages(images)) {
IrisImages.addShadowColorImages(images, shadowTargetsSupplier.get(), null);
}
}
private boolean isPostChain;
private boolean isMainBound = true;
@@ -933,6 +984,56 @@ public class DeferredWorldRenderingPipeline implements WorldRenderingPipeline, R
}
}
public CloudSetting getDHCloudSetting() {
return dhCloudSetting;
}
public Optional<ProgramSource> getDHTerrainShader() {
return resolver.resolve(ProgramId.DhTerrain);
}
public Optional<ProgramSource> getDHGenericShader() {
return resolver.resolve(ProgramId.DhGeneric);
}
public Optional<ProgramSource> getDHWaterShader() {
return resolver.resolve(ProgramId.DhWater);
}
public Optional<ProgramSource> getDHShadowShader() {
return resolver.resolve(ProgramId.DhShadow);
}
public CustomUniforms getCustomUniforms() {
return customUniforms;
}
public GlFramebuffer createDHFramebuffer(ProgramSource sources, boolean trans) {
return renderTargets.createDHFramebuffer(trans ? flippedAfterTranslucent : flippedAfterPrepare,
sources.getDirectives().getDrawBuffers());
}
public ImmutableSet<Integer> getFlippedBeforeShadow() {
return flippedBeforeShadow;
}
public ImmutableSet<Integer> getFlippedAfterPrepare() {
return flippedAfterPrepare;
}
public ImmutableSet<Integer> getFlippedAfterTranslucent() {
return flippedAfterTranslucent;
}
public GlFramebuffer createDHFramebufferShadow(ProgramSource sources) {
return shadowRenderTargets.createDHFramebuffer(ImmutableSet.of(), new int[]{0, 1});
}
public boolean hasShadowRenderTargets() {
return shadowRenderTargets != null;
}
private final class Pass {
@Nullable
private final Program program;
@@ -973,12 +1074,8 @@ public class DeferredWorldRenderingPipeline implements WorldRenderingPipeline, R
GLStateManager.glViewport(0, 0, main.framebufferWidth, main.framebufferHeight);
}
if (program != null) {
program.use();
}
DeferredWorldRenderingPipeline.this.customUniforms.push(this);
// Apply state overrides before program.use() so that uniforms (e.g. iris_currentAlphaTest)
// read the correct GLSM state during upload, not the stale vanilla state.
if (alphaTestOverride != null) {
alphaTestOverride.apply();
} else {
@@ -996,6 +1093,12 @@ public class DeferredWorldRenderingPipeline implements WorldRenderingPipeline, R
if (bufferBlendOverrides != null && !bufferBlendOverrides.isEmpty()) {
bufferBlendOverrides.forEach(BufferBlendOverride::apply);
}
if (program != null) {
program.use();
}
DeferredWorldRenderingPipeline.this.customUniforms.push(this);
}
public void stopUsing() {
@@ -1028,6 +1131,7 @@ public class DeferredWorldRenderingPipeline implements WorldRenderingPipeline, R
BlendModeOverride.restore();
AlphaTestOverride.restore();
FullScreenQuadRenderer.clearLocCache();
destroyPasses(table);
// Destroy the composite rendering pipeline
@@ -1077,6 +1181,7 @@ public class DeferredWorldRenderingPipeline implements WorldRenderingPipeline, R
// While it's possible to just clear them instead and reuse them, we'd need to investigate whether or not this
// would help performance.
renderTargets.destroy();
dhCompat.clearPipeline();
// destroy the shadow render targets
if (shadowRenderTargets != null) {
@@ -130,7 +130,7 @@ public class FixedFunctionWorldRenderingPipeline implements WorldRenderingPipeli
return new FrameUpdateNotifier();
}
private static final DHCompat DH_COMPAT = new DHCompat();
private static final DHCompat DH_COMPAT = new DHCompat(null, false);
@Override
public DHCompat getDHCompat() {
@@ -39,6 +39,9 @@ public class PatchedShaderPrinter {
}
public static void debugPatchedShaders(String name, String vertex, String geometry, String tessControl, String tessEval, String fragment, String compute) {
if (!Iris.getIrisConfig().areDebugOptionsEnabled()) {
return;
}
if (prettyPrintShaders) {
final Path debugOutDir = Minecraft.getMinecraft().mcDataDir.toPath().resolve("patched_shaders");
if (!outputLocationCleared) {
@@ -10,6 +10,7 @@ import com.gtnewhorizons.angelica.glsm.RenderSystem;
import com.gtnewhorizons.angelica.rendering.RenderingState;
import com.gtnewhorizons.angelica.rendering.celeritas.CeleritasWorldRenderer;
import net.coderbot.iris.Iris;
import net.coderbot.iris.compat.dh.DHCompat;
import net.coderbot.iris.gui.option.IrisVideoSettings;
import net.coderbot.iris.layer.GbufferPrograms;
import net.coderbot.iris.shaderpack.PackDirectives;
@@ -43,6 +44,7 @@ import net.minecraft.profiler.Profiler;
import net.minecraft.tileentity.TileEntity;
import org.embeddedt.embeddium.impl.render.viewport.ViewportProvider;
import org.joml.Matrix4f;
import org.joml.Matrix4fc;
import org.joml.Vector3d;
import org.joml.Vector3f;
import org.joml.Vector4f;
@@ -68,6 +70,8 @@ public class ShadowRenderer {
public static final List<TileEntity> globalTileEntities = new ArrayList<>();
public static boolean ACTIVE = false;
public static Frustrum FRUSTUM;
private static final Comparator<Entity> ENTITY_CLASS_COMPARATOR = Comparator.comparingInt(a -> System.identityHashCode(a.getClass()));
private static final NonCullingFrustum NON_CULLING_FRUSTUM = new NonCullingFrustum();
private static final CullEverythingFrustum CULL_EVERYTHING_FRUSTUM = new CullEverythingFrustum();
@@ -111,12 +115,16 @@ public class ShadowRenderer {
private double lastBoxCullerDistance = -1;
private double lastAdvancedBoxCullerDistance = -1;
private double lastTileEntityCullerDistance = -1;
private final boolean shouldRenderDH;
private final float nearPlane, farPlane;
public ShadowRenderer(ProgramSource shadow, PackDirectives directives, ShadowRenderTargets shadowRenderTargets, ShadowCompositeRenderer compositeRenderer) {
this.profiler = Minecraft.getMinecraft().mcProfiler;
final PackShadowDirectives shadowDirectives = directives.getShadowDirectives();
this.nearPlane = shadowDirectives.getNearPlane();
this.farPlane = shadowDirectives.getFarPlane();
this.halfPlaneLength = shadowDirectives.getDistance();
this.voxelDistance = shadowDirectives.getVoxelDistance();
@@ -129,6 +137,7 @@ public class ShadowRenderer {
this.shouldRenderEntities = shadowDirectives.shouldRenderEntities();
this.shouldRenderPlayer = shadowDirectives.shouldRenderPlayer();
this.shouldRenderBlockEntities = shadowDirectives.shouldRenderBlockEntities();
this.shouldRenderDH = shadowDirectives.isDhShadowEnabled().orElse(false);
this.compositeRenderer = compositeRenderer;
@@ -348,14 +357,16 @@ public class ShadowRenderer {
shadowLightVectorCache.set(shadowLightPosition.x(), shadowLightPosition.y(), shadowLightPosition.z());
shadowLightVectorCache.normalize();
Matrix4fc projView = ((shouldRenderDH && DHCompat.hasRenderingEnabled()) ? DHCompat.getProjection() : RenderingState.INSTANCE.getProjectionMatrix());
if (hasSafeZone) {
BoxCuller distanceCuller = new BoxCuller(halfPlaneLength * renderMultiplier);
SafeZoneCullingFrustum safeZoneFrustum = new SafeZoneCullingFrustum(
RenderingState.INSTANCE.getModelViewMatrix(), RenderingState.INSTANCE.getProjectionMatrix(),
RenderingState.INSTANCE.getModelViewMatrix(), projView,
shadowLightVectorCache, boxCuller, distanceCuller);
return holder.setInfo(safeZoneFrustum, distanceInfo, cullingInfo);
} else {
cachedAdvancedFrustum.init(RenderingState.INSTANCE.getModelViewMatrix(), RenderingState.INSTANCE.getProjectionMatrix(), shadowLightVectorCache, boxCuller);
cachedAdvancedFrustum.init(RenderingState.INSTANCE.getModelViewMatrix(), projView, shadowLightVectorCache, boxCuller);
return holder.setInfo(cachedAdvancedFrustum, distanceInfo, cullingInfo);
}
}
@@ -630,12 +641,12 @@ public class ShadowRenderer {
final MatrixStack modelView = getShadowModelView();
MODELVIEW.set(modelView.peek().getModel());
final Matrix4f shadowProjection;
final Matrix4f shadowProjection;
if (this.fov != null) {
// If FOV is not null, the pack wants a perspective based projection matrix. (This is to support legacy packs)
shadowProjection = ShadowMatrices.createPerspectiveMatrix(this.fov);
shadowProjection = ShadowMatrices.createPerspectiveMatrix(this.fov);
} else {
shadowProjection = ShadowMatrices.createOrthoMatrix(halfPlaneLength);
shadowProjection = ShadowMatrices.createOrthoMatrix(halfPlaneLength, nearPlane < 0 ? -DHCompat.getRenderDistance() : nearPlane, farPlane < 0 ? DHCompat.getRenderDistance() : farPlane);
}
PROJECTION.set(shadowProjection);
@@ -649,6 +660,7 @@ public class ShadowRenderer {
profiler.startSection("initialize frustum");
terrainFrustumHolder = createShadowFrustum(renderDistanceMultiplier, terrainFrustumHolder);
FRUSTUM = terrainFrustumHolder.getFrustum();
// Use the player/entity position for shadow rendering
final Vector3d entityPos = playerCamera.getEntityPos();
@@ -21,6 +21,7 @@ class CoreTransformHelper {
transformer.injectVariable("uniform mat4 iris_ProjectionMatrixInverse;");
transformer.injectVariable("uniform mat3 iris_NormalMatrix;");
transformer.injectVariable("uniform mat4 iris_LightmapTextureMatrix;");
transformer.injectVariable("uniform mat4 iris_TextureMatrix;");
final Map<String, String> renames = new HashMap<>();
renames.put("gl_ModelViewMatrix", "iris_ModelViewMatrix");
@@ -32,12 +33,12 @@ class CoreTransformHelper {
final Map<String, String> replacements = new HashMap<>();
replacements.put("gl_ModelViewProjectionMatrix", "(iris_ProjectionMatrix * iris_ModelViewMatrix)");
replacements.put("gl_TextureMatrix[0]", "mat4(1.0)");
replacements.put("gl_TextureMatrix[0]", "iris_TextureMatrix");
replacements.put("gl_TextureMatrix[1]", "iris_LightmapTextureMatrix");
replacements.forEach(transformer::replaceExpression);
// Catch any remaining gl_TextureMatrix references (e.g. [2]-[7])
transformer.replaceExpression("gl_TextureMatrix", "mat4[8](mat4(1.0), iris_LightmapTextureMatrix, mat4(1.0), mat4(1.0), mat4(1.0), mat4(1.0), mat4(1.0), mat4(1.0))");
transformer.replaceExpression("gl_TextureMatrix", "mat4[8](iris_TextureMatrix, iris_LightmapTextureMatrix, mat4(1.0), mat4(1.0), mat4(1.0), mat4(1.0), mat4(1.0), mat4(1.0))");
}
/**
@@ -0,0 +1,114 @@
package net.coderbot.iris.pipeline.transform;
import net.coderbot.iris.gl.shader.ShaderType;
import net.coderbot.iris.pipeline.transform.parameter.Parameters;
import org.taumc.glsl.Transformer;
public class DHGenericTransformer {
public static void transform(Transformer transformer, Parameters parameters, int glslVersion) {
CommonTransformer.transform(transformer, parameters, true, glslVersion);
transformer.replaceExpression("gl_TextureMatrix[0]", "mat4(1.0)");
transformer.replaceExpression("gl_TextureMatrix[1]", "mat4(1.0)");
transformer.rename("gl_ProjectionMatrix", "iris_ProjectionMatrix");
if (parameters.type == ShaderType.VERTEX) {
// Alias of gl_MultiTexCoord1 on 1.15+ for OptiFine
// See https://github.com/IrisShaders/Iris/issues/1149
transformer.rename("gl_MultiTexCoord2", "gl_MultiTexCoord1");
transformer.replaceExpression("gl_MultiTexCoord0", "vec4(0.0, 0.0, 0.0, 1.0)");
transformer.replaceExpression("gl_MultiTexCoord1", "vec4(_vert_tex_light_coord, 0.0, 1.0)");
replaceGlMultiTexCoordBounded(transformer, 4, 7);
}
transformer.rename("gl_Color", "_vert_color");
if (parameters.type == ShaderType.VERTEX) {
transformer.replaceExpression("gl_Normal", "_vert_normal");
}
transformer.replaceExpression("gl_NormalMatrix", "iris_NormalMatrix");
addIfNotExists(transformer, "iris_NormalMatrix", "uniform mat3 iris_NormalMatrix;");
addIfNotExists(transformer, "iris_ModelViewMatrixInverse", "uniform mat4 iris_ModelViewMatrixInverse;");
addIfNotExists(transformer, "iris_ProjectionMatrixInverse", "uniform mat4 iris_ProjectionMatrixInverse;");
transformer.rename("gl_ModelViewMatrix", "iris_ModelViewMatrix");
transformer.rename("gl_ModelViewMatrixInverse", "iris_ModelViewMatrixInverse");
transformer.rename("gl_ProjectionMatrixInverse", "iris_ProjectionMatrixInverse");
if (parameters.type == ShaderType.VERTEX) {
if (transformer.containsCall("ftransform")) {
transformer.injectFunction("vec4 ftransform() { return gl_ModelViewProjectionMatrix * gl_Vertex; }");
}
addIfNotExists(transformer, "iris_ProjectionMatrix", "uniform mat4 iris_ProjectionMatrix;");
addIfNotExists(transformer, "iris_ModelViewMatrix", "uniform mat4 iris_ModelViewMatrix;");
transformer.injectFunction("vec4 getVertexPosition() { return vec4(_vert_position, 1.0); }");
transformer.replaceExpression("gl_Vertex", "getVertexPosition()");
injectVertInit(transformer);
} else {
addIfNotExists(transformer, "iris_ModelViewMatrix", "uniform mat4 iris_ModelViewMatrix;");
addIfNotExists(transformer, "iris_ProjectionMatrix", "uniform mat4 iris_ProjectionMatrix;");
}
transformer.replaceExpression("gl_ModelViewProjectionMatrix", "(iris_ProjectionMatrix * iris_ModelViewMatrix)");
ShaderTransformer.applyIntelHd4000Workaround(transformer);
}
public static void injectVertInit(Transformer transformer) {
addIfNotExists(transformer, "_vert_position", "vec3 _vert_position;");
addIfNotExists(transformer, "_vert_tex_light_coord", "vec2 _vert_tex_light_coord;");
addIfNotExists(transformer, "dhMaterialId", "int dhMaterialId;");
addIfNotExists(transformer, "_vert_color", "vec4 _vert_color;");
addIfNotExists(transformer, "_vert_normal", "vec3 _vert_normal;");
addIfNotExists(transformer, "uOffsetChunk", "uniform ivec3 uOffsetChunk;");
addIfNotExists(transformer, "uOffsetSubChunk", "uniform vec3 uOffsetSubChunk;");
addIfNotExists(transformer, "uCameraPosChunk", "uniform ivec3 uCameraPosChunk;");
addIfNotExists(transformer, "uCameraPosSubChunk", "uniform vec3 uCameraPosSubChunk;");
addIfNotExists(transformer, "uSkyLight", "uniform int uSkyLight;");
addIfNotExists(transformer, "uBlockLight", "uniform int uBlockLight;");
addIfNotExists(transformer, "iris_color", "in vec4 iris_color;");
addIfNotExists(transformer, "aScale", "in vec3 aScale;");
addIfNotExists(transformer, "aTranslateChunk", "in ivec3 aTranslateChunk;");
addIfNotExists(transformer, "aTranslateSubChunk", "in vec3 aTranslateSubChunk;");
addIfNotExists(transformer, "aMaterial", "in int aMaterial;");
addIfNotExists(transformer, "vPosition", "in vec3 vPosition;");
transformer.injectFunction("const vec3 irisNormals[6] = vec3[](vec3(0,0,-1), vec3(0,0,1), vec3(-1,0,0), vec3(1,0,0), vec3(0,-1,0), vec3(0,1,0));");
transformer.injectFunction(
"void _vert_init() {"
+ " vec3 trans = vec3(aTranslateChunk + uOffsetChunk - uCameraPosChunk) * 16.0;"
+ " trans += (aTranslateSubChunk + uOffsetSubChunk - uCameraPosSubChunk);"
+ " mat4 transform = mat4("
+ " aScale.x, 0.0, 0.0, 0.0,"
+ " 0.0, aScale.y, 0.0, 0.0,"
+ " 0.0, 0.0, aScale.z, 0.0,"
+ " trans.x, trans.y, trans.z, 1.0"
+ " );"
+ " _vert_position = (transform * vec4(vPosition, 1.0)).xyz;"
+ " _vert_normal = irisNormals[int(floor(float(gl_VertexID) / 4.0))];"
+ " float blockLight = (float(uBlockLight) + 0.5) / 16.0;"
+ " float skyLight = (float(uSkyLight) + 0.5) / 16.0;"
+ " _vert_tex_light_coord = vec2(blockLight, skyLight);"
+ " dhMaterialId = aMaterial;"
+ " _vert_color = iris_color;"
+ " }"
);
transformer.prependMain("_vert_init();");
}
private static void addIfNotExists(Transformer transformer, String name, String code) {
if (!transformer.hasVariable(name)) {
transformer.injectVariable(code);
}
}
private static void replaceGlMultiTexCoordBounded(Transformer transformer, int from, int to) {
for (int i = from; i <= to; i++) {
transformer.replaceExpression("gl_MultiTexCoord" + i, "vec4(0.0, 0.0, 0.0, 1.0)");
}
}
}
@@ -0,0 +1,106 @@
package net.coderbot.iris.pipeline.transform;
import net.coderbot.iris.gl.shader.ShaderType;
import net.coderbot.iris.pipeline.transform.parameter.Parameters;
import org.taumc.glsl.Transformer;
public class DHTerrainTransformer {
public static void transform(Transformer transformer, Parameters parameters, int glslVersion) {
CommonTransformer.transform(transformer, parameters, true, glslVersion);
transformer.replaceExpression("gl_TextureMatrix[0]", "mat4(1.0)");
transformer.replaceExpression("gl_TextureMatrix[1]", "mat4(1.0)");
transformer.rename("gl_ProjectionMatrix", "iris_ProjectionMatrix");
if (parameters.type == ShaderType.VERTEX) {
// Alias of gl_MultiTexCoord1 on 1.15+ for OptiFine
// See https://github.com/IrisShaders/Iris/issues/1149
transformer.rename("gl_MultiTexCoord2", "gl_MultiTexCoord1");
transformer.replaceExpression("gl_MultiTexCoord0", "vec4(0.0, 0.0, 0.0, 1.0)");
transformer.replaceExpression("gl_MultiTexCoord1", "vec4(_vert_tex_light_coord, 0.0, 1.0)");
replaceGlMultiTexCoordBounded(transformer, 4, 7);
}
transformer.rename("gl_Color", "_vert_color");
if (parameters.type == ShaderType.VERTEX) {
transformer.replaceExpression("gl_Normal", "_vert_normal");
}
transformer.replaceExpression("gl_NormalMatrix", "iris_NormalMatrix");
addIfNotExists(transformer, "iris_NormalMatrix", "uniform mat3 iris_NormalMatrix;");
addIfNotExists(transformer, "iris_ModelViewMatrixInverse", "uniform mat4 iris_ModelViewMatrixInverse;");
addIfNotExists(transformer, "iris_ProjectionMatrixInverse", "uniform mat4 iris_ProjectionMatrixInverse;");
transformer.rename("gl_ModelViewMatrix", "iris_ModelViewMatrix");
transformer.rename("gl_ModelViewMatrixInverse", "iris_ModelViewMatrixInverse");
transformer.rename("gl_ProjectionMatrixInverse", "iris_ProjectionMatrixInverse");
if (parameters.type == ShaderType.VERTEX) {
if (transformer.containsCall("ftransform")) {
transformer.injectFunction("vec4 ftransform() { return gl_ModelViewProjectionMatrix * gl_Vertex; }");
}
addIfNotExists(transformer, "iris_ProjectionMatrix", "uniform mat4 iris_ProjectionMatrix;");
addIfNotExists(transformer, "iris_ModelViewMatrix", "uniform mat4 iris_ModelViewMatrix;");
transformer.injectFunction("vec4 getVertexPosition() { return vec4(modelOffset + _vert_position, 1.0); }");
transformer.replaceExpression("gl_Vertex", "getVertexPosition()");
injectVertInit(transformer);
} else {
addIfNotExists(transformer, "iris_ModelViewMatrix", "uniform mat4 iris_ModelViewMatrix;");
addIfNotExists(transformer, "iris_ProjectionMatrix", "uniform mat4 iris_ProjectionMatrix;");
}
transformer.replaceExpression("gl_ModelViewProjectionMatrix", "(iris_ProjectionMatrix * iris_ModelViewMatrix)");
ShaderTransformer.applyIntelHd4000Workaround(transformer);
}
public static void injectVertInit(Transformer transformer) {
addIfNotExists(transformer, "_vert_position", "vec3 _vert_position;");
addIfNotExists(transformer, "_vert_tex_light_coord", "vec2 _vert_tex_light_coord;");
addIfNotExists(transformer, "dhMaterialId", "int dhMaterialId;");
addIfNotExists(transformer, "_vert_color", "vec4 _vert_color;");
addIfNotExists(transformer, "_vert_normal", "vec3 _vert_normal;");
addIfNotExists(transformer, "mircoOffset", "uniform float mircoOffset;");
addIfNotExists(transformer, "modelOffset", "uniform vec3 modelOffset;");
addIfNotExists(transformer, "iris_color", "in vec4 iris_color;");
addIfNotExists(transformer, "vPosition", "in uvec4 vPosition;");
addIfNotExists(transformer, "irisExtra", "in uvec4 irisExtra;");
transformer.injectFunction("const vec3 irisNormals[6] = vec3[](vec3(0,-1,0), vec3(0,1,0), vec3(0,0,-1), vec3(0,0,1), vec3(-1,0,0), vec3(1,0,0));");
transformer.injectFunction(
"void _vert_init() {"
+ " uint meta = vPosition.a;"
+ " uint mirco = (meta & 0xFF00u) >> 8u;"
+ " float mx = (mirco & 1u) != 0u ? mircoOffset : 0.0;"
+ " mx = (mirco & 2u) != 0u ? -mx : mx;"
+ " float my = (mirco & 4u) != 0u ? mircoOffset : 0.0;"
+ " my = (mirco & 8u) != 0u ? -my : my;"
+ " float mz = (mirco & 16u) != 0u ? mircoOffset : 0.0;"
+ " mz = (mirco & 32u) != 0u ? -mz : mz;"
+ " uint lights = meta & 0xFFu;"
+ " _vert_position = (vPosition.xyz + vec3(mx, my, mz));"
+ " _vert_normal = irisNormals[int(irisExtra.y)];"
+ " dhMaterialId = int(irisExtra.x);"
+ " _vert_tex_light_coord = vec2((float(lights / 16u) + 0.5) / 16.0, (mod(float(lights), 16.0) + 0.5) / 16.0);"
+ " _vert_color = iris_color;"
+ " }"
);
transformer.prependMain("_vert_init();");
}
private static void addIfNotExists(Transformer transformer, String name, String code) {
if (!transformer.hasVariable(name)) {
transformer.injectVariable(code);
}
}
private static void replaceGlMultiTexCoordBounded(Transformer transformer, int from, int to) {
for (int i = from; i <= to; i++) {
transformer.replaceExpression("gl_MultiTexCoord" + i, "vec4(0.0, 0.0, 0.0, 1.0)");
}
}
}
@@ -4,5 +4,7 @@ public enum Patch {
ATTRIBUTES,
CELERITAS_TERRAIN,
COMPOSITE,
COMPUTE
COMPUTE,
DH_TERRAIN,
DH_GENERIC
}
@@ -439,6 +439,12 @@ public class ShaderTransformer {
case COMPUTE:
ComputeTransformer.transform(transformer, parameters, versionInt);
break;
case DH_TERRAIN:
DHTerrainTransformer.transform(transformer, parameters, versionInt);
break;
case DH_GENERIC:
DHGenericTransformer.transform(transformer, parameters, versionInt);
break;
default:
throw new IllegalStateException("Unknown patch type: " + patchType.name());
}
@@ -7,6 +7,7 @@ import net.coderbot.iris.helpers.Tri;
import net.coderbot.iris.pipeline.transform.parameter.AttributeParameters;
import net.coderbot.iris.pipeline.transform.parameter.CeleritasTerrainParameters;
import net.coderbot.iris.pipeline.transform.parameter.ComputeParameters;
import net.coderbot.iris.pipeline.transform.parameter.DHParameters;
import net.coderbot.iris.pipeline.transform.parameter.Parameters;
import net.coderbot.iris.pipeline.transform.parameter.TextureStageParameters;
import net.coderbot.iris.shaderpack.texture.TextureStage;
@@ -127,6 +128,23 @@ public class TransformPatcher {
return transform(vertex, geometry, tessControl, tessEval, fragment, new TextureStageParameters(Patch.COMPOSITE, stage, textureMap));
}
public static Map<PatchShaderType, String> patchDHTerrain(
String name, String vertex, String tessControl, String tessEval, String geometry, String fragment,
Object2ObjectMap<Tri<String, TextureType, TextureStage>, String> textureMap) {
return transform(vertex, geometry, tessControl, tessEval, fragment,
new DHParameters(Patch.DH_TERRAIN, textureMap));
}
public static Map<PatchShaderType, String> patchDHGeneric(
String name, String vertex, String tessControl, String tessEval, String geometry, String fragment,
Object2ObjectMap<Tri<String, TextureType, TextureStage>, String> textureMap) {
return transform(vertex, geometry, tessControl, tessEval, fragment,
new DHParameters(Patch.DH_GENERIC, textureMap));
}
public static Map<PatchShaderType, String> patchComposite(String vertex, String geometry, String fragment, TextureStage stage, Object2ObjectMap<Tri<String, TextureType, TextureStage>, String> textureMap) {
return patchComposite(vertex, geometry, null, null, fragment, stage, textureMap);
}
@@ -0,0 +1,18 @@
package net.coderbot.iris.pipeline.transform.parameter;
import it.unimi.dsi.fastutil.objects.Object2ObjectMap;
import net.coderbot.iris.gl.texture.TextureType;
import net.coderbot.iris.helpers.Tri;
import net.coderbot.iris.pipeline.transform.Patch;
import net.coderbot.iris.shaderpack.texture.TextureStage;
public class DHParameters extends Parameters {
public DHParameters(Patch patch, Object2ObjectMap<Tri<String, TextureType, TextureStage>, String> textureMap) {
super(patch, textureMap);
}
@Override
public TextureStage getTextureStage() {
return TextureStage.GBUFFERS_AND_SHADOW;
}
}
@@ -78,6 +78,11 @@ public class FullScreenQuadRenderer {
/** Per-program cached uniform locations: [mvLoc, projLoc]. Populated on first miss. */
private static final Int2ObjectOpenHashMap<int[]> compositeLocCache = new Int2ObjectOpenHashMap<>();
/** Clear cached uniform locations. Must be called when composite programs are destroyed (e.g. shader reload). */
public static void clearLocCache() {
compositeLocCache.clear();
}
public static void uploadCompositeMatrices() {
final int program = GLStateManager.glGetInteger(GL20.GL_CURRENT_PROGRAM);
if (program == 0) return;
@@ -248,6 +248,16 @@ public class RenderTargets {
return framebuffer;
}
public GlFramebuffer createDHFramebuffer(ImmutableSet<Integer> stageWritesToAlt, int[] drawBuffers) {
if (drawBuffers.length == 0) {
return createEmptyFramebuffer();
}
ImmutableSet<Integer> stageWritesToMain = invert(stageWritesToAlt, drawBuffers);
return createColorFramebuffer(stageWritesToMain, drawBuffers);
}
public GlFramebuffer createGbufferFramebuffer(ImmutableSet<Integer> stageWritesToAlt, int[] drawBuffers) {
if (drawBuffers.length == 0) {
return createEmptyFramebuffer();
@@ -28,7 +28,7 @@ public class PackDirectives {
@Getter private float eyeBrightnessHalfLife;
@Getter private float centerDepthHalfLife;
@Getter private CloudSetting cloudSetting;
@Getter private CloudSetting dhCloudSetting;
private CloudSetting dhCloudSetting;
private boolean underwaterOverlay;
private boolean vignette;
private boolean sun;
@@ -181,6 +181,10 @@ public class PackDirectives {
return concurrentCompute;
}
public CloudSetting getDHCloudSetting() {
return dhCloudSetting;
}
private static float clamp(float val, float lo, float hi) {
return Math.max(lo, Math.min(hi, val));
}
@@ -30,6 +30,8 @@ public class PackShadowDirectives {
private final boolean shouldRenderPlayer;
private final boolean shouldRenderBlockEntities;
@Getter private final ShadowCullState cullingState;
private final OptionalBoolean dhShadowEnabled;
private float nearPlane, farPlane;
private final ImmutableList<DepthSamplingSettings> depthSamplingSettings;
private final ImmutableList<SamplingSettings> colorSamplingSettings;
@@ -53,6 +55,8 @@ public class PackShadowDirectives {
// shadowRenderDistanceMul to a nonzero value, since having a high shadow render distance will impact
// performance quite heavily on most systems.
this.distance = 160.0f;
this.nearPlane = 0.05f;
this.farPlane = 256.0f;
this.voxelDistance = 0.0f;
// By default, shadows are not culled based on distance from the player. However, pack authors may
@@ -81,6 +85,7 @@ public class PackShadowDirectives {
this.shouldRenderBlockEntities = properties.getShadowBlockEntities().orElse(true);
this.cullingState = properties.getShadowCulling();
this.shadowEnabled = properties.getShadowEnabled();
this.dhShadowEnabled = properties.getDhShadowEnabled();
this.depthSamplingSettings = ImmutableList.of(new DepthSamplingSettings(), new DepthSamplingSettings());
@@ -97,6 +102,8 @@ public class PackShadowDirectives {
this.resolution = shadowDirectives.resolution;
this.fov = shadowDirectives.fov;
this.distance = shadowDirectives.distance;
this.nearPlane = shadowDirectives.nearPlane;
this.farPlane = shadowDirectives.farPlane;
this.voxelDistance = shadowDirectives.voxelDistance;
this.distanceRenderMul = shadowDirectives.distanceRenderMul;
this.entityShadowDistanceMul = shadowDirectives.entityShadowDistanceMul;
@@ -111,6 +118,7 @@ public class PackShadowDirectives {
this.depthSamplingSettings = shadowDirectives.depthSamplingSettings;
this.colorSamplingSettings = shadowDirectives.colorSamplingSettings;
this.shadowEnabled = shadowDirectives.shadowEnabled;
this.dhShadowEnabled = shadowDirectives.dhShadowEnabled;
}
public int getResolution() {
@@ -125,6 +133,18 @@ public class PackShadowDirectives {
return distance;
}
public float getNearPlane() {
return nearPlane;
}
public float getFarPlane() {
return farPlane;
}
public OptionalBoolean isDhShadowEnabled() {
return dhShadowEnabled;
}
public float getVoxelDistance() {
return voxelDistance;
}
@@ -186,7 +206,8 @@ public class PackShadowDirectives {
directives.acceptCommentFloatDirective("SHADOWHPL", distance -> this.distance = distance);
directives.acceptConstFloatDirective("shadowDistance", distance -> this.distance = distance);
directives.acceptConstFloatDirective("shadowNearPlane", nearPlane -> this.nearPlane = nearPlane);
directives.acceptConstFloatDirective("shadowFarPlane", farPlane -> this.farPlane = farPlane);
directives.acceptConstFloatDirective("entityShadowDistanceMul", distance -> this.entityShadowDistanceMul = distance);
directives.acceptConstFloatDirective("shadowDistanceRenderMul", distanceRenderMul -> {
@@ -43,6 +43,7 @@ public class ProgramSet {
private final ProgramSource gbuffersGlint;
private final ProgramSource gbuffersEntityEyes;
private final ProgramSource gbuffersBlock;
private final ProgramSource gbuffersBlockTrans;
private final ProgramSource gbuffersHand;
private final ProgramSource[] deferred;
@@ -55,7 +56,10 @@ public class ProgramSet {
private final ComputeSource[][] compositeCompute;
private final ProgramSource compositeFinal;
private final ComputeSource[] finalCompute;
private final ProgramSource dhTerrain;
private final ProgramSource dhGeneric;
private final ProgramSource dhWater;
private final ProgramSource dhShadow;
private final ShaderPack pack;
@@ -116,7 +120,12 @@ public class ProgramSet {
this.gbuffersGlint = readProgramSource(directory, sourceProvider, "gbuffers_armor_glint", this, shaderProperties);
this.gbuffersEntityEyes = readProgramSource(directory, sourceProvider, "gbuffers_spidereyes", this, shaderProperties);
this.gbuffersBlock = readProgramSource(directory, sourceProvider, "gbuffers_block", this, shaderProperties);
this.gbuffersBlockTrans = readProgramSource(directory, sourceProvider, "gbuffers_block_translucent", this, shaderProperties);
this.gbuffersHand = readProgramSource(directory, sourceProvider, "gbuffers_hand", this, shaderProperties);
this.dhTerrain = readProgramSource(directory, sourceProvider, "dh_terrain", this, shaderProperties);
this.dhGeneric = readProgramSource(directory, sourceProvider, "dh_generic", this, shaderProperties);
this.dhWater = readProgramSource(directory, sourceProvider, "dh_water", this, shaderProperties);
this.dhShadow = readProgramSource(directory, sourceProvider, "dh_shadow", this, shaderProperties);
this.deferred = readProgramArray(directory, sourceProvider, "deferred", shaderProperties);
this.deferredCompute = new ComputeSource[deferred.length][];
@@ -216,8 +225,8 @@ public class ProgramSet {
programs.addAll (Arrays.asList(
gbuffersBasic, gbuffersBeaconBeam, gbuffersTextured, gbuffersTexturedLit, gbuffersTerrain,
gbuffersDamagedBlock, gbuffersSkyBasic, gbuffersSkyTextured, gbuffersClouds, gbuffersWeather,
gbuffersEntities, gbuffersEntitiesTrans, gbuffersEntitiesGlowing, gbuffersGlint, gbuffersEntityEyes, gbuffersBlock,
gbuffersHand
gbuffersEntities, gbuffersEntitiesTrans, gbuffersEntitiesGlowing, gbuffersGlint, gbuffersEntityEyes, gbuffersBlock, gbuffersBlockTrans,
gbuffersHand, dhShadow, dhTerrain, dhGeneric, dhWater
));
for (ComputeSource[] computeSources : compositeCompute) {
@@ -377,36 +386,61 @@ public class ProgramSet {
return gbuffersBlock.requireValid();
}
public Optional<ProgramSource> getGbuffersBlockTrans() {
return gbuffersBlockTrans.requireValid();
}
public Optional<ProgramSource> getGbuffersHand() {
return gbuffersHand.requireValid();
}
public Optional<ProgramSource> getDhTerrain() {
return dhTerrain.requireValid();
}
public Optional<ProgramSource> getDhGeneric() {
return dhGeneric.requireValid();
}
public Optional<ProgramSource> getDhWater() {
return dhWater.requireValid();
}
public Optional<ProgramSource> getDhShadow() {
return dhShadow.requireValid();
}
public Optional<ProgramSource> get(ProgramId programId) {
return switch (programId) {
case Shadow -> getShadow();
case Basic -> getGbuffersBasic();
case Line -> gbuffersLine.requireValid();
case Textured -> getGbuffersTextured();
case TexturedLit -> getGbuffersTexturedLit();
case SkyBasic -> getGbuffersSkyBasic();
case SkyTextured -> getGbuffersSkyTextured();
case Clouds -> getGbuffersClouds();
case Terrain -> getGbuffersTerrain();
case DamagedBlock -> getGbuffersDamagedBlock();
case Block -> getGbuffersBlock();
case BeaconBeam -> getGbuffersBeaconBeam();
case Entities -> getGbuffersEntities();
case EntitiesTrans -> getGbuffersEntitiesTrans();
case EntitiesGlowing -> getGbuffersEntitiesGlowing();
case ArmorGlint -> getGbuffersGlint();
case SpiderEyes -> getGbuffersEntityEyes();
case Hand -> getGbuffersHand();
case Weather -> getGbuffersWeather();
case Water -> getGbuffersWater();
case HandWater -> getGbuffersHandWater();
case Final -> getCompositeFinal();
default -> Optional.empty();
};
return switch (programId) {
case Shadow -> getShadow();
case Basic -> getGbuffersBasic();
case Line -> gbuffersLine.requireValid();
case Textured -> getGbuffersTextured();
case TexturedLit -> getGbuffersTexturedLit();
case SkyBasic -> getGbuffersSkyBasic();
case SkyTextured -> getGbuffersSkyTextured();
case Clouds -> getGbuffersClouds();
case Terrain -> getGbuffersTerrain();
case DamagedBlock -> getGbuffersDamagedBlock();
case Block -> getGbuffersBlock();
case BlockTrans -> getGbuffersBlockTrans();
case BeaconBeam -> getGbuffersBeaconBeam();
case Entities -> getGbuffersEntities();
case EntitiesTrans -> getGbuffersEntitiesTrans();
case EntitiesGlowing -> getGbuffersEntitiesGlowing();
case ArmorGlint -> getGbuffersGlint();
case SpiderEyes -> getGbuffersEntityEyes();
case Hand -> getGbuffersHand();
case Weather -> getGbuffersWeather();
case Water -> getGbuffersWater();
case HandWater -> getGbuffersHandWater();
case Final -> getCompositeFinal();
case DhTerrain -> getDhTerrain();
case DhGeneric -> getDhGeneric();
case DhWater -> getDhWater();
case DhShadow -> getDhShadow();
default -> Optional.empty();
};
}
public ProgramSource[] getDeferred() {
@@ -97,6 +97,7 @@ public class ShaderProperties {
@Getter private OptionalBoolean prepareBeforeShadow = OptionalBoolean.DEFAULT;
@Getter private List<String> sliderOptions = new ArrayList<>();
@Getter private final Map<String, List<String>> profiles = new LinkedHashMap<>();
@Getter private final Map<String, List<String>> profiles2 = new LinkedHashMap<>();
private List<String> mainScreenOptions = null;
@Getter private final Map<String, List<String>> subScreenOptions = new HashMap<>();
private Integer mainScreenColumnCount = null;
@@ -494,15 +495,15 @@ public class ShaderProperties {
customUniforms.addVariable(parts[0], parts[1], value, false);
});
handlePassDirective("uniform.", key, value, pass -> {
String[] parts = pass.split("\\.");
if (parts.length != 2) {
Iris.logger.warn("Custom uniforms sould take the form of `uniform.<type>.<name> = <expression>. Ignoring " + key);
return;
}
handlePassDirective("uniform.", key, value, pass -> {
String[] parts = pass.split("\\.");
if (parts.length != 2) {
Iris.logger.warn("Custom uniforms sould take the form of `uniform.<type>.<name> = <expression>. Ignoring " + key);
return;
}
customUniforms.addVariable(parts[0], parts[1], value, true);
});
customUniforms.addVariable(parts[0], parts[1], value, true);
});
// TODO: Buffer size directives
// TODO: Conditional program enabling directives
@@ -517,6 +518,7 @@ public class ShaderProperties {
// the last definition being used, should be tested if behavior matches OptiFine
handleWhitespacedListDirective(key, value, "sliders", sliders -> sliderOptions = sliders);
handlePrefixedWhitespacedListDirective("profile.", key, value, profiles::put);
handlePrefixedWhitespacedListDirective("profile2.", key, value, profiles2::put);
if (handleIntDirective(key, value, "screen.columns", columns -> mainScreenColumnCount = columns)) {
return;
@@ -7,7 +7,8 @@ public enum ProgramGroup {
Gbuffers("gbuffers"),
Deferred("deferred"),
Composite("composite"),
Final("final")
Final("final"),
Dh("dh")
;
private final String baseName;
@@ -1,6 +1,11 @@
package net.coderbot.iris.shaderpack.loading;
import com.gtnewhorizons.angelica.glsm.states.BlendState;
import net.coderbot.iris.gl.blending.AlphaTest;
import net.coderbot.iris.gl.blending.AlphaTestFunction;
import net.coderbot.iris.gl.blending.AlphaTestOverride;
import net.coderbot.iris.gl.blending.BlendModeOverride;
import org.lwjgl.opengl.GL11;
import java.util.Objects;
import java.util.Optional;
@@ -26,6 +31,7 @@ public enum ProgramId {
DamagedBlock(ProgramGroup.Gbuffers, "damagedblock", Terrain),
Block(ProgramGroup.Gbuffers, "block", Terrain),
BlockTrans(ProgramGroup.Gbuffers, "block_translucent", Block, BlendModeOverride.OFF),
BeaconBeam(ProgramGroup.Gbuffers, "beaconbeam", Textured),
Item(ProgramGroup.Gbuffers, "item", TexturedLit),
@@ -33,12 +39,18 @@ public enum ProgramId {
EntitiesTrans(ProgramGroup.Gbuffers, "entities_translucent", Entities),
EntitiesGlowing(ProgramGroup.Gbuffers, "entities_glowing", Entities),
ArmorGlint(ProgramGroup.Gbuffers, "armor_glint", Textured),
SpiderEyes(ProgramGroup.Gbuffers, "spidereyes", Textured),
SpiderEyes(ProgramGroup.Gbuffers, "spidereyes", Textured,
new BlendModeOverride(new BlendState(GL11.GL_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ZERO, GL11.GL_ONE)),
new AlphaTestOverride(new AlphaTest(AlphaTestFunction.GREATER, 0.0001F))),
Hand(ProgramGroup.Gbuffers, "hand", TexturedLit),
Weather(ProgramGroup.Gbuffers, "weather", TexturedLit),
Water(ProgramGroup.Gbuffers, "water", Terrain),
HandWater(ProgramGroup.Gbuffers, "hand_water", Hand),
DhTerrain(ProgramGroup.Dh, "terrain"),
DhWater(ProgramGroup.Dh, "water", DhTerrain),
DhGeneric(ProgramGroup.Dh, "generic", DhTerrain),
DhShadow(ProgramGroup.Dh, "shadow"),
Final(ProgramGroup.Final, ""),
;
@@ -47,12 +59,14 @@ public enum ProgramId {
private final String sourceName;
private final ProgramId fallback;
private final BlendModeOverride defaultBlendOverride;
private final AlphaTestOverride defaultAlphaTestOverride;
ProgramId(ProgramGroup group, String name) {
this.group = group;
this.sourceName = name.isEmpty() ? group.getBaseName() : group.getBaseName() + "_" + name;
this.fallback = null;
this.defaultBlendOverride = null;
this.defaultAlphaTestOverride = null;
}
ProgramId(ProgramGroup group, String name, ProgramId fallback) {
@@ -60,6 +74,7 @@ public enum ProgramId {
this.sourceName = name.isEmpty() ? group.getBaseName() : group.getBaseName() + "_" + name;
this.fallback = Objects.requireNonNull(fallback);
this.defaultBlendOverride = null;
this.defaultAlphaTestOverride = null;
}
ProgramId(ProgramGroup group, String name, ProgramId fallback, BlendModeOverride defaultBlendOverride) {
@@ -67,6 +82,15 @@ public enum ProgramId {
this.sourceName = name.isEmpty() ? group.getBaseName() : group.getBaseName() + "_" + name;
this.fallback = Objects.requireNonNull(fallback);
this.defaultBlendOverride = defaultBlendOverride;
this.defaultAlphaTestOverride = null;
}
ProgramId(ProgramGroup group, String name, ProgramId fallback, BlendModeOverride defaultBlendOverride, AlphaTestOverride defaultAlphaTestOverride) {
this.group = group;
this.sourceName = name.isEmpty() ? group.getBaseName() : group.getBaseName() + "_" + name;
this.fallback = Objects.requireNonNull(fallback);
this.defaultBlendOverride = defaultBlendOverride;
this.defaultAlphaTestOverride = defaultAlphaTestOverride;
}
public ProgramGroup getGroup() {
@@ -84,4 +108,8 @@ public enum ProgramId {
public BlendModeOverride getBlendModeOverride() {
return defaultBlendOverride;
}
public AlphaTestOverride getDefaultAlphaTestOverride() {
return defaultAlphaTestOverride;
}
}
@@ -1,6 +1,7 @@
package net.coderbot.iris.shaderpack.option.menu;
import com.google.common.collect.Lists;
import lombok.Getter;
import net.coderbot.iris.Iris;
import net.coderbot.iris.shaderpack.ShaderProperties;
import net.coderbot.iris.shaderpack.option.ProfileSet;
@@ -21,10 +22,12 @@ public class OptionMenuContainer {
private final List<String> usedOptions = new ArrayList<>();
private final List<String> unusedOptions = new ArrayList<>(); // To be used when screens contain a "*" element
private final Map<List<OptionMenuElement>, Integer> unusedOptionDumpQueue = new HashMap<>(); // Used by screens with "*" element
private final ProfileSet profiles;
@Getter private final ProfileSet profiles;
@Getter private final ProfileSet profiles2;
public OptionMenuContainer(ShaderProperties shaderProperties, ShaderPackOptions shaderPackOptions, ProfileSet profiles) {
this.profiles = profiles;
this.profiles2 = ProfileSet.fromTree(shaderProperties.getProfiles2(), shaderPackOptions.getOptionSet());
// note: if the Shader Pack does not provide a list of options for the main screen, then dump all options on to
// the main screen by default.
@@ -68,10 +71,6 @@ public class OptionMenuContainer {
}
}
public ProfileSet getProfiles() {
return profiles;
}
// Screens will call this when they contain a "*" element, so that the list of
// unused options can be added after all other screens have been resolved
public void queueForUnusedOptionDump(int index, List<OptionMenuElement> elementList) {
@@ -12,6 +12,7 @@ public abstract class OptionMenuElement {
private static final String ELEMENT_EMPTY = "<empty>";
private static final String ELEMENT_PROFILE = "<profile>";
private static final String ELEMENT_PROFILE2 = "<profile2>";
public static OptionMenuElement create(String elementString, OptionMenuContainer container, ShaderProperties shaderProperties, ShaderPackOptions shaderPackOptions) throws IllegalArgumentException {
// Empty element
@@ -24,6 +25,13 @@ public abstract class OptionMenuElement {
// null indicates that the element should be forgotten (not treated as empty)
return container.getProfiles().size() > 0 ? new OptionMenuProfileElement(container.getProfiles(), shaderPackOptions.getOptionSet(), shaderPackOptions.getOptionValues()) : null;
}
// Second profile element
if (ELEMENT_PROFILE2.equals(elementString)) {
// null indicates that the element should be forgotten (not treated as empty)
return container.getProfiles2().size() > 0
? ProfileElementTracker.markSecondProfileSet(new OptionMenuProfileElement(container.getProfiles2(), shaderPackOptions.getOptionSet(), shaderPackOptions.getOptionValues()))
: null;
}
// Link to sub screen element
if (elementString.startsWith("[") && elementString.endsWith("]")) {
return new OptionMenuLinkElement(elementString.substring(1, elementString.length() - 1));
@@ -0,0 +1,22 @@
package net.coderbot.iris.shaderpack.option.menu;
import java.util.Collections;
import java.util.Set;
import java.util.WeakHashMap;
public final class ProfileElementTracker {
private static final Set<Object> SECOND_PROFILE_ELEMENTS =
Collections.newSetFromMap(new WeakHashMap<>());
private ProfileElementTracker() {
}
public static <T> T markSecondProfileSet(T element) {
SECOND_PROFILE_ELEMENTS.add(element);
return element;
}
public static boolean isSecondProfileSet(Object element) {
return SECOND_PROFILE_ELEMENTS.contains(element);
}
}
@@ -11,16 +11,16 @@ public class ShadowMatrices {
// NB: These matrices are in column-major order, not row-major order like what you'd expect!
public static Matrix4f createOrthoMatrix(float halfPlaneLength) {
public static Matrix4f createOrthoMatrix(float halfPlaneLength, float nearPlane, float farPlane) {
return new Matrix4f(
// column 1
1.0f / halfPlaneLength, 0f, 0f, 0f,
// column 2
0f, 1.0f / halfPlaneLength, 0f, 0f,
// column 3
0f, 0f, 2.0f / (NEAR - FAR), 0f,
0f, 0f, 2.0f / (nearPlane - farPlane), 0f,
// column 4
0f, 0f, -(FAR + NEAR) / (FAR - NEAR), 1f
0f, 0f, -(farPlane + nearPlane) / (farPlane - nearPlane), 1f
);
}
@@ -104,7 +104,7 @@ public class ShadowMatrices {
0f, 0f, -1.000390648841858f, 1f
);
test("ortho projection hpl=32", expected, createOrthoMatrix(32.0f));
test("ortho projection hpl=32", expected, createOrthoMatrix(32.0f, 0.05f, 256.0f));
// const float shadowDistance = 110.0;
// /* SHADOWHPL:110.0 */
@@ -115,7 +115,7 @@ public class ShadowMatrices {
0, 0, -1.000390648841858f, 1
);
test("ortho projection hpl=110", expected110, createOrthoMatrix(110.0f));
test("ortho projection hpl=110", expected110, createOrthoMatrix(110.0f, 0.05f, 256.0f));
Matrix4f expected90Proj = new Matrix4f(
1.0f, 0.0f, 0.0f, 0.0f,
@@ -206,6 +206,20 @@ public class ShadowRenderTargets {
return framebuffer;
}
public GlFramebuffer createDHFramebuffer(ImmutableSet<Integer> stageWritesToAlt, int[] drawBuffers) {
if (drawBuffers.length == 0) {
return createEmptyFramebuffer();
}
ImmutableSet<Integer> stageWritesToMain = invert(stageWritesToAlt, drawBuffers);
GlFramebuffer framebuffer = createColorFramebuffer(stageWritesToMain, drawBuffers);
framebuffer.addDepthAttachment(mainDepth.getTextureId());
return framebuffer;
}
public GlFramebuffer createShadowFramebuffer(ImmutableSet<Integer> stageWritesToAlt, int[] drawBuffers) {
if (drawBuffers.length == 0) {
return createEmptyFramebuffer();
@@ -1,5 +1,8 @@
package net.coderbot.iris.shadows.frustum;
import cpw.mods.fml.common.Optional;
import com.seibel.distanthorizons.api.interfaces.override.rendering.IDhApiShadowCullingFrustum;
import com.seibel.distanthorizons.api.objects.math.DhApiMat4f;
import net.minecraft.client.renderer.culling.Frustrum;
import net.minecraft.util.AxisAlignedBB;
import org.embeddedt.embeddium.impl.render.viewport.Viewport;
@@ -7,7 +10,8 @@ import org.embeddedt.embeddium.impl.render.viewport.ViewportProvider;
import org.embeddedt.embeddium.impl.render.viewport.frustum.Frustum;
import org.joml.Vector3d;
public class CullEverythingFrustum extends Frustrum implements ViewportProvider, Frustum {
@Optional.Interface(modid = "distanthorizons", iface = "com.seibel.distanthorizons.api.interfaces.override.rendering.IDhApiShadowCullingFrustum")
public class CullEverythingFrustum extends Frustrum implements ViewportProvider, Frustum, IDhApiShadowCullingFrustum {
private final Vector3d position = new Vector3d();
@Override
@@ -24,4 +28,16 @@ public class CullEverythingFrustum extends Frustrum implements ViewportProvider,
public Viewport sodium$createViewport() {
return new Viewport(this, position.set(xPosition, yPosition, zPosition));
}
@Optional.Method(modid = "distanthorizons")
@Override
public void update(int worldMinBlockY, int worldMaxBlockY, DhApiMat4f worldViewProjection) {
}
@Optional.Method(modid = "distanthorizons")
@Override
public boolean intersects(int lodBlockPosMinX, int lodBlockPosMinZ, int lodBlockWidth, int lodDetailLevel) {
return false;
}
}
@@ -1,5 +1,8 @@
package net.coderbot.iris.shadows.frustum.advanced;
import cpw.mods.fml.common.Optional;
import com.seibel.distanthorizons.api.interfaces.override.rendering.IDhApiShadowCullingFrustum;
import com.seibel.distanthorizons.api.objects.math.DhApiMat4f;
import net.coderbot.iris.shadows.frustum.BoxCuller;
import net.minecraft.client.renderer.culling.Frustrum;
import net.minecraft.util.AxisAlignedBB;
@@ -8,6 +11,7 @@ import org.embeddedt.embeddium.impl.render.viewport.ViewportProvider;
import org.embeddedt.embeddium.impl.render.viewport.frustum.Frustum;
import org.joml.Math;
import org.joml.Matrix4f;
import org.joml.Matrix4fc;
import org.joml.Vector3d;
import org.joml.Vector3f;
import org.joml.Vector4f;
@@ -32,7 +36,8 @@ import org.joml.Vector4f;
* are not sensitive to the specific internal ordering of planes and corners, in order to avoid potential bugs at the
* cost of slightly more computations.</p>
*/
public class AdvancedShadowCullingFrustum extends Frustrum implements ViewportProvider, Frustum {
@Optional.Interface(modid = "distanthorizons", iface = "com.seibel.distanthorizons.api.interfaces.override.rendering.IDhApiShadowCullingFrustum")
public class AdvancedShadowCullingFrustum extends Frustrum implements ViewportProvider, Frustum, IDhApiShadowCullingFrustum {
private static final int MAX_CLIPPING_PLANES = 13;
/**
@@ -79,6 +84,8 @@ public class AdvancedShadowCullingFrustum extends Frustrum implements ViewportPr
private final BaseClippingPlanes baseClippingPlanes = new BaseClippingPlanes();
private final boolean[] isBackArray = new boolean[6];
private int worldMinYDH;
private int worldMaxYDH;
public AdvancedShadowCullingFrustum() {
for (int i = 0; i < MAX_CLIPPING_PLANES; i++) {
@@ -86,7 +93,7 @@ public class AdvancedShadowCullingFrustum extends Frustrum implements ViewportPr
}
}
public void init(Matrix4f playerView, Matrix4f playerProjection, Vector3f shadowLightVector, BoxCuller boxCuller) {
public void init(Matrix4fc playerView, Matrix4fc playerProjection, Vector3f shadowLightVector, BoxCuller boxCuller) {
this.shadowLightVectorFromOrigin.set(shadowLightVector);
this.boxCuller = boxCuller;
this.planeCount = 0;
@@ -298,4 +305,17 @@ public class AdvancedShadowCullingFrustum extends Frustrum implements ViewportPr
return true;
}
@Optional.Method(modid = "distanthorizons")
@Override
public void update(int worldMinBlockY, int worldMaxBlockY, DhApiMat4f worldViewProjection) {
this.worldMinYDH = worldMinBlockY;
this.worldMaxYDH = worldMaxBlockY;
}
@Optional.Method(modid = "distanthorizons")
@Override
public boolean intersects(int lodBlockPosMinX, int lodBlockPosMinZ, int lodBlockWidth, int lodDetailLevel) {
return this.isVisible(lodBlockPosMinX, this.worldMinYDH, lodBlockPosMinZ, lodBlockPosMinX + lodBlockWidth, this.worldMaxYDH, lodBlockPosMinZ + lodBlockWidth);
}
}
@@ -1,6 +1,7 @@
package net.coderbot.iris.shadows.frustum.advanced;
import org.joml.Matrix4f;
import org.joml.Matrix4fc;
import org.joml.Vector4f;
public class BaseClippingPlanes {
@@ -13,7 +14,7 @@ public class BaseClippingPlanes {
}
}
public void init(Matrix4f view, Matrix4f projection) {
public void init(Matrix4fc view, Matrix4fc projection) {
// Transform = Transpose(Projection x View)
transformScratch.set(projection);
transformScratch.mul(view);
@@ -3,12 +3,13 @@ package net.coderbot.iris.shadows.frustum.advanced;
import net.coderbot.iris.shadows.frustum.BoxCuller;
import net.minecraft.util.AxisAlignedBB;
import org.joml.Matrix4f;
import org.joml.Matrix4fc;
import org.joml.Vector3f;
public class SafeZoneCullingFrustum extends AdvancedShadowCullingFrustum {
private final BoxCuller distanceCuller;
public SafeZoneCullingFrustum(Matrix4f playerView, Matrix4f playerProjection, Vector3f shadowLightVector, BoxCuller voxelCuller, BoxCuller distanceCuller) {
public SafeZoneCullingFrustum(Matrix4fc playerView, Matrix4fc playerProjection, Vector3f shadowLightVector, BoxCuller voxelCuller, BoxCuller distanceCuller) {
super();
init(playerView, playerProjection, shadowLightVector, voxelCuller);
this.distanceCuller = distanceCuller;
@@ -1,5 +1,8 @@
package net.coderbot.iris.shadows.frustum.fallback;
import cpw.mods.fml.common.Optional;
import com.seibel.distanthorizons.api.interfaces.override.rendering.IDhApiShadowCullingFrustum;
import com.seibel.distanthorizons.api.objects.math.DhApiMat4f;
import net.coderbot.iris.shadows.frustum.BoxCuller;
import net.minecraft.client.renderer.culling.Frustrum;
import net.minecraft.util.AxisAlignedBB;
@@ -8,9 +11,12 @@ import org.embeddedt.embeddium.impl.render.viewport.ViewportProvider;
import org.embeddedt.embeddium.impl.render.viewport.frustum.Frustum;
import org.joml.Vector3d;
public class BoxCullingFrustum extends Frustrum implements ViewportProvider, Frustum {
@Optional.Interface(modid = "distanthorizons", iface = "com.seibel.distanthorizons.api.interfaces.override.rendering.IDhApiShadowCullingFrustum")
public class BoxCullingFrustum extends Frustrum implements ViewportProvider, Frustum, IDhApiShadowCullingFrustum {
private final BoxCuller boxCuller;
private final Vector3d position = new Vector3d();
private int worldMinYDH;
private int worldMaxYDH;
public BoxCullingFrustum(BoxCuller boxCuller) {
this.boxCuller = boxCuller;
@@ -36,4 +42,17 @@ public class BoxCullingFrustum extends Frustrum implements ViewportProvider, Fru
public Viewport sodium$createViewport() {
return new Viewport(this, position.set(xPosition, yPosition, zPosition));
}
@Optional.Method(modid = "distanthorizons")
@Override
public void update(int worldMinBlockY, int worldMaxBlockY, DhApiMat4f worldViewProjection) {
this.worldMinYDH = worldMinBlockY;
this.worldMaxYDH = worldMaxBlockY;
}
@Optional.Method(modid = "distanthorizons")
@Override
public boolean intersects(int lodBlockPosMinX, int lodBlockPosMinZ, int lodBlockWidth, int lodDetailLevel) {
return !boxCuller.isCulled(lodBlockPosMinX, this.worldMinYDH, lodBlockPosMinZ, lodBlockPosMinX + lodBlockWidth, this.worldMaxYDH, lodBlockPosMinZ + lodBlockWidth);
}
}
@@ -1,5 +1,8 @@
package net.coderbot.iris.shadows.frustum.fallback;
import cpw.mods.fml.common.Optional;
import com.seibel.distanthorizons.api.interfaces.override.rendering.IDhApiShadowCullingFrustum;
import com.seibel.distanthorizons.api.objects.math.DhApiMat4f;
import net.minecraft.client.renderer.culling.Frustrum;
import net.minecraft.util.AxisAlignedBB;
import org.embeddedt.embeddium.impl.render.viewport.Viewport;
@@ -7,7 +10,8 @@ import org.embeddedt.embeddium.impl.render.viewport.ViewportProvider;
import org.embeddedt.embeddium.impl.render.viewport.frustum.Frustum;
import org.joml.Vector3d;
public class NonCullingFrustum extends Frustrum implements ViewportProvider, Frustum {
@Optional.Interface(modid = "distanthorizons", iface = "com.seibel.distanthorizons.api.interfaces.override.rendering.IDhApiShadowCullingFrustum")
public class NonCullingFrustum extends Frustrum implements ViewportProvider, Frustum, IDhApiShadowCullingFrustum {
private final Vector3d position = new Vector3d();
@Override
@@ -24,4 +28,17 @@ public class NonCullingFrustum extends Frustrum implements ViewportProvider, Fru
public Viewport sodium$createViewport() {
return new Viewport(this, position.set(xPosition, yPosition, zPosition));
}
@Optional.Method(modid = "distanthorizons")
@Override
public void update(int worldMinBlockY, int worldMaxBlockY, DhApiMat4f worldViewProjection) {
}
@Optional.Method(modid = "distanthorizons")
@Override
public boolean intersects(int lodBlockPosMinX, int lodBlockPosMinZ, int lodBlockWidth, int lodDetailLevel) {
return true;
}
}
@@ -4,8 +4,12 @@ import com.gtnewhorizons.angelica.rendering.RenderingState;
import lombok.Getter;
import net.coderbot.iris.gl.uniform.UniformHolder;
import net.minecraft.client.Minecraft;
import org.joml.Matrix3f;
import org.joml.Vector3d;
import org.joml.Vector3dc;
import org.joml.Vector3f;
import org.joml.Vector3fc;
import org.joml.Vector3i;
import org.joml.Vector3ic;
import static net.coderbot.iris.gl.uniform.UniformUpdateFrequency.ONCE;
import static net.coderbot.iris.gl.uniform.UniformUpdateFrequency.PER_FRAME;
@@ -15,6 +19,8 @@ import static net.coderbot.iris.gl.uniform.UniformUpdateFrequency.PER_FRAME;
*/
public class CameraUniforms {
private static final Minecraft client = Minecraft.getMinecraft();
private static final Vector3f tempVec3f = new Vector3f();
private static final Vector3i tempVec3i = new Vector3i();
private CameraUniforms() {
}
@@ -27,7 +33,27 @@ public class CameraUniforms {
.uniform1f(PER_FRAME, "far", CameraUniforms::getRenderDistanceInBlocks)
.uniform3d(PER_FRAME, "cameraPosition", tracker::getCurrentCameraPosition)
.uniform1f(PER_FRAME, "eyeAltitude", tracker::getCurrentCameraPositionY)
.uniform3d(PER_FRAME, "previousCameraPosition", tracker::getPreviousCameraPosition);
.uniform3d(PER_FRAME, "previousCameraPosition", tracker::getPreviousCameraPosition)
.uniform3i(PER_FRAME, "cameraPositionInt", () -> getCameraPositionInt(getUnshiftedCameraPosition()))
.uniform3f(PER_FRAME, "cameraPositionFract", () -> getCameraPositionFract(getUnshiftedCameraPosition()))
.uniform3i(PER_FRAME, "previousCameraPositionInt", () -> getCameraPositionInt(tracker.getPreviousCameraPositionUnshifted()))
.uniform3f(PER_FRAME, "previousCameraPositionFract", () -> getCameraPositionFract(tracker.getPreviousCameraPositionUnshifted()));
}
public static Vector3fc getCameraPositionFract(Vector3d originalPos) {
return tempVec3f.set(
(float) (originalPos.x - Math.floor(originalPos.x)),
(float) (originalPos.y - Math.floor(originalPos.y)),
(float) (originalPos.z - Math.floor(originalPos.z))
);
}
public static Vector3ic getCameraPositionInt(Vector3d originalPos) {
return tempVec3i.set(
(int) Math.floor(originalPos.x),
(int) Math.floor(originalPos.y),
(int) Math.floor(originalPos.z)
);
}
private static int getRenderDistanceInBlocks() {
@@ -35,7 +61,7 @@ public class CameraUniforms {
return client.gameSettings.renderDistanceChunks * 16;
}
public static Vector3dc getUnshiftedCameraPosition() {
public static Vector3d getUnshiftedCameraPosition() {
return RenderingState.INSTANCE.getCameraPosition();
}
@@ -50,10 +76,12 @@ public class CameraUniforms {
private static final double TP_RANGE = 1000;
@Getter
private Vector3d previousCameraPosition = new Vector3d();
private Vector3d previousCameraPosition = new Vector3d();
@Getter
private Vector3d currentCameraPosition = new Vector3d();
private Vector3d currentCameraPosition = new Vector3d();
private final Vector3d shift = new Vector3d();
private Vector3d previousCameraPositionUnshifted = new Vector3d();
private Vector3d currentCameraPositionUnshifted = new Vector3d();
CameraPositionTracker(FrameUpdateNotifier notifier) {
notifier.addListener(this::update);
@@ -61,7 +89,9 @@ public class CameraUniforms {
private void update() {
previousCameraPosition.set(currentCameraPosition);
previousCameraPositionUnshifted = currentCameraPositionUnshifted;
currentCameraPosition.set(getUnshiftedCameraPosition()).add(shift);
currentCameraPositionUnshifted.set(getUnshiftedCameraPosition());
updateShift();
}
@@ -104,8 +134,12 @@ public class CameraUniforms {
previousCameraPosition.z += dZ;
}
public double getCurrentCameraPositionY() {
public double getCurrentCameraPositionY() {
return currentCameraPosition.y;
}
public Vector3d getPreviousCameraPositionUnshifted() {
return previousCameraPositionUnshifted;
}
}
}
@@ -7,6 +7,7 @@ import com.gtnewhorizons.angelica.glsm.texture.TextureInfo;
import com.gtnewhorizons.angelica.glsm.texture.TextureInfoCache;
import com.gtnewhorizons.angelica.client.rendering.TextureTracker;
import com.gtnewhorizons.angelica.mixins.interfaces.EntityRendererAccessor;
import net.coderbot.iris.compat.dh.DHCompat;
import net.coderbot.iris.gl.state.FogMode;
import net.coderbot.iris.gl.state.ValueUpdateNotifier;
import net.coderbot.iris.gl.uniform.DynamicUniformHolder;
@@ -137,7 +138,10 @@ public final class CommonUniforms {
.uniform1f(PER_TICK, "rainStrength", CommonUniforms::getRainStrength)
.uniform1f(PER_TICK, "wetness", new SmoothedFloat(directives.getWetnessHalfLife(), directives.getDrynessHalfLife(), CommonUniforms::getRainStrength, updateNotifier))
.uniform3d(PER_FRAME, "skyColor", CommonUniforms::getSkyColor)
.uniform3d(PER_FRAME, "fogColor", GLStateManager::getFogColor);
.uniform3d(PER_FRAME, "fogColor", GLStateManager::getFogColor)
.uniform1f(PER_FRAME, "dhFarPlane", DHCompat::getFarPlane)
.uniform1f(PER_FRAME, "dhNearPlane", DHCompat::getNearPlane)
.uniform1i(PER_FRAME, "dhRenderDistance", DHCompat::getRenderDistance);
}
private static boolean isOnGround() {
@@ -14,6 +14,7 @@ public class ExternallyManagedUniforms {
addMat4(uniformHolder, "iris_ProjectionMatrix");
addMat4(uniformHolder, "iris_ProjectionMatrixInverse");
addMat4(uniformHolder, "iris_LightmapTextureMatrix");
addMat4(uniformHolder, "iris_TextureMatrix");
addMat4(uniformHolder, "u_ModelViewProjectionMatrix");
addMat3(uniformHolder, "iris_NormalMatrix");
uniformHolder.externallyManagedUniform("heavyFog", UniformType.BOOL);
@@ -1,11 +1,13 @@
package net.coderbot.iris.uniforms;
import com.gtnewhorizons.angelica.rendering.RenderingState;
import net.coderbot.iris.compat.dh.DHCompat;
import net.coderbot.iris.gl.uniform.UniformHolder;
import net.coderbot.iris.pipeline.ShadowRenderer;
import net.coderbot.iris.shaderpack.PackDirectives;
import net.coderbot.iris.shadow.ShadowMatrices;
import org.joml.Matrix4f;
import org.joml.Matrix4fc;
import java.util.function.Supplier;
@@ -20,27 +22,37 @@ public final class MatrixUniforms {
// TODO: In some cases, gbufferProjectionInverse takes on a value much different than OptiFine...
// We need to audit Mojang's linear algebra.
addMatrix(uniforms, "Projection", RenderingState.INSTANCE::getProjectionMatrix);
addDHMatrix(uniforms, "Projection", DHCompat::getProjection);
addShadowMatrix(uniforms, "ModelView", () -> ShadowRenderer.createShadowModelView(directives.getSunPathRotation(), directives.getShadowDirectives().getIntervalSize()).peek().getModel());
addShadowMatrix(uniforms, "Projection", () -> ShadowMatrices.createOrthoMatrix(directives.getShadowDirectives().getDistance()));
addShadowMatrix(uniforms, "Projection", () -> ShadowMatrices.createOrthoMatrix(directives.getShadowDirectives().getDistance(), directives.getShadowDirectives().getNearPlane() < 0 ? -DHCompat.getRenderDistance() : directives.getShadowDirectives().getNearPlane(),
directives.getShadowDirectives().getFarPlane() < 0 ? DHCompat.getRenderDistance() : directives.getShadowDirectives().getFarPlane()));
}
private static void addMatrix(UniformHolder uniforms, String name, Supplier<Matrix4f> supplier) {
private static void addMatrix(UniformHolder uniforms, String name, Supplier<Matrix4fc> supplier) {
uniforms
.uniformMatrix(PER_FRAME, "gbuffer" + name, supplier)
.uniformMatrix(PER_FRAME, "gbuffer" + name + "Inverse", new Inverted(supplier))
.uniformMatrix(PER_FRAME, "gbufferPrevious" + name, new Previous(supplier));
}
private static void addShadowMatrix(UniformHolder uniforms, String name, Supplier<Matrix4f> supplier) {
private static void addDHMatrix(UniformHolder uniforms, String name, Supplier<Matrix4fc> supplier) {
uniforms
.uniformMatrix(PER_FRAME, "dh" + name, supplier)
.uniformMatrix(PER_FRAME, "dh" + name + "Inverse", new Inverted(supplier))
.uniformMatrix(PER_FRAME, "dhPrevious" + name, new Previous(supplier));
}
private static void addShadowMatrix(UniformHolder uniforms, String name, Supplier<Matrix4fc> supplier) {
uniforms
.uniformMatrix(PER_FRAME, "shadow" + name, supplier)
.uniformMatrix(PER_FRAME, "shadow" + name + "Inverse", new Inverted(supplier));
}
private static class Inverted implements Supplier<Matrix4f> {
private final Supplier<Matrix4f> parent;
private static class Inverted implements Supplier<Matrix4fc> {
private final Supplier<Matrix4fc> parent;
Inverted(Supplier<Matrix4f> parent) {
Inverted(Supplier<Matrix4fc> parent) {
this.parent = parent;
}
@@ -56,11 +68,11 @@ public final class MatrixUniforms {
}
private static class Previous implements Supplier<Matrix4f> {
private final Supplier<Matrix4f> parent;
private Matrix4f previous;
private static class Previous implements Supplier<Matrix4fc> {
private final Supplier<Matrix4fc> parent;
private Matrix4fc previous;
Previous(Supplier<Matrix4f> parent) {
Previous(Supplier<Matrix4fc> parent) {
this.parent = parent;
this.previous = new Matrix4f();
}
@@ -25,7 +25,8 @@ import org.joml.Vector2f;
import org.joml.Vector2i;
import org.joml.Vector3d;
import org.joml.Vector3f;
import org.joml.Vector3i;
import org.joml.Vector3fc;
import org.joml.Vector3ic;
import org.joml.Vector4f;
import java.util.Collection;
@@ -116,12 +117,12 @@ public class CustomUniformFixedInputUniformsHolder {
}
@Override
public Builder uniform3f(UniformUpdateFrequency updateFrequency, String name, Supplier<Vector3f> value) {
public Builder uniform3f(UniformUpdateFrequency updateFrequency, String name, Supplier<Vector3fc> value) {
return this.put(name, new Float3VectorCachedUniform(name, updateFrequency, value));
}
@Override
public Builder uniform3i(UniformUpdateFrequency updateFrequency, String name, Supplier<Vector3i> value) {
public Builder uniform3i(UniformUpdateFrequency updateFrequency, String name, Supplier<Vector3ic> value) {
return this.put(name, new Int3VectorCachedUniform(name, updateFrequency, value));
}
@@ -172,7 +173,7 @@ public class CustomUniformFixedInputUniformsHolder {
@Override
public UniformHolder uniformMatrix(
UniformUpdateFrequency updateFrequency, String name, Supplier<Matrix4f> value) {
UniformUpdateFrequency updateFrequency, String name, Supplier<Matrix4fc> value) {
return this.put(name, new Float4MatrixCachedUniform(name, updateFrequency, value));
}
@@ -4,23 +4,24 @@ import net.coderbot.iris.gl.uniform.UniformUpdateFrequency;
import net.coderbot.iris.parsing.VectorType;
import org.joml.Vector3f;
import com.gtnewhorizons.angelica.glsm.GLStateManager;
import org.joml.Vector3fc;
import java.util.function.Supplier;
public class Float3VectorCachedUniform extends VectorCachedUniform<Vector3f> {
public class Float3VectorCachedUniform extends VectorCachedUniform<Vector3fc> {
public Float3VectorCachedUniform(String name, UniformUpdateFrequency updateFrequency, Supplier<Vector3f> supplier) {
public Float3VectorCachedUniform(String name, UniformUpdateFrequency updateFrequency, Supplier<Vector3fc> supplier) {
super(name, updateFrequency, new Vector3f(), supplier);
}
@Override
protected void setFrom(Vector3f other) {
this.cached.set(other);
protected void setFrom(Vector3fc other) {
((Vector3f)this.cached).set(other);
}
@Override
public void push(int location) {
GLStateManager.glUniform3f(location, this.cached.x, this.cached.y, this.cached.z);
GLStateManager.glUniform3f(location, this.cached.x(), this.cached.y(), this.cached.z());
}
@Override
@@ -4,21 +4,22 @@ import net.coderbot.iris.gl.uniform.UniformUpdateFrequency;
import net.coderbot.iris.parsing.MatrixType;
import org.joml.Matrix4f;
import com.gtnewhorizons.angelica.glsm.GLStateManager;
import org.joml.Matrix4fc;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.util.function.Supplier;
public class Float4MatrixCachedUniform extends VectorCachedUniform<Matrix4f> {
public class Float4MatrixCachedUniform extends VectorCachedUniform<Matrix4fc> {
final private FloatBuffer buffer = ByteBuffer.allocateDirect(16 << 2).order(ByteOrder.nativeOrder()).asFloatBuffer();
public Float4MatrixCachedUniform(String name, UniformUpdateFrequency updateFrequency, Supplier<Matrix4f> supplier) {
public Float4MatrixCachedUniform(String name, UniformUpdateFrequency updateFrequency, Supplier<Matrix4fc> supplier) {
super(name, updateFrequency, new Matrix4f(), supplier);
}
@Override
protected void setFrom(Matrix4f other) {
protected void setFrom(Matrix4fc other) {
((Matrix4f) this.cached).set(other);
}
@@ -4,23 +4,24 @@ import net.coderbot.iris.gl.uniform.UniformUpdateFrequency;
import net.coderbot.iris.parsing.VectorType;
import org.joml.Vector3i;
import com.gtnewhorizons.angelica.glsm.GLStateManager;
import org.joml.Vector3ic;
import java.util.function.Supplier;
public class Int3VectorCachedUniform extends VectorCachedUniform<Vector3i> {
public class Int3VectorCachedUniform extends VectorCachedUniform<Vector3ic> {
public Int3VectorCachedUniform(String name, UniformUpdateFrequency updateFrequency, Supplier<Vector3i> supplier) {
public Int3VectorCachedUniform(String name, UniformUpdateFrequency updateFrequency, Supplier<Vector3ic> supplier) {
super(name, updateFrequency, new Vector3i(), supplier);
}
@Override
protected void setFrom(Vector3i other) {
this.cached.set(other);
protected void setFrom(Vector3ic other) {
((Vector3i)this.cached).set(other);
}
@Override
public void push(int location) {
GLStateManager.glUniform3i(location, this.cached.x, this.cached.y, this.cached.z);
GLStateManager.glUniform3i(location, this.cached.x(), this.cached.y(), this.cached.z());
}
@Override
Loaded 100 of 116 files, more files were not shown because too many files have changed in this diff. Show more