Fix DSA binding restore and liquid colors (#2192)

This commit is contained in:
Jason Mitchell authored and GitHub committed 2026-10-02 21:48:24 -07:00
1 parent 1587a12cd7
commit 85892c0f7f
23 files changed
+374 -494

No files matched your search

@@ -586,18 +586,6 @@ public class RenderSystem {
RENDER_BACKEND.clearTexImage(texture, level, format, type);
}
public static void textureStorage1D(int texture, int target, int levels, int internalFormat, int width) {
dsaState.textureStorage1D(texture, target, levels, internalFormat, width);
}
public static void textureStorage2D(int texture, int target, int levels, int internalFormat, int width, int height) {
dsaState.textureStorage2D(texture, target, levels, internalFormat, width, height);
}
public static void textureStorage3D(int texture, int target, int levels, int internalFormat, int width, int height, int depth) {
dsaState.textureStorage3D(texture, target, levels, internalFormat, width, height, depth);
}
public static int getMaxGlslVersion() {
return maxGlslVersion;
}
@@ -1254,31 +1254,6 @@ public final class Lwjgl2GLRenderBackend extends RenderBackend {
GL42.glTexStorage2D(target, levels, internalFormat, width, height);
}
@Override
public void textureStorage2D(int texture, int levels, int internalFormat, int width, int height) {
ARBDirectStateAccess.glTextureStorage2D(texture, levels, internalFormat, width, height);
}
@Override
public void texStorage1D(int target, int levels, int internalFormat, int width) {
GL42.glTexStorage1D(target, levels, internalFormat, width);
}
@Override
public void texStorage3D(int target, int levels, int internalFormat, int width, int height, int depth) {
GL42.glTexStorage3D(target, levels, internalFormat, width, height, depth);
}
@Override
public void textureStorage1D(int texture, int levels, int internalFormat, int width) {
ARBDirectStateAccess.glTextureStorage1D(texture, levels, internalFormat, width);
}
@Override
public void textureStorage3D(int texture, int levels, int internalFormat, int width, int height, int depth) {
ARBDirectStateAccess.glTextureStorage3D(texture, levels, internalFormat, width, height, depth);
}
@Override
public void generateTextureMipmap(int texture) {
ARBDirectStateAccess.glGenerateTextureMipmap(texture);
@@ -612,12 +612,7 @@ public abstract class RenderBackend {
public abstract void textureParameteri(int texture, int target, int pname, int param);
public abstract void textureParameterf(int texture, int target, int pname, float param);
public abstract void textureParameteriv(int texture, int target, int pname, IntBuffer params);
public abstract void texStorage1D(int target, int levels, int internalFormat, int width);
public abstract void texStorage2D(int target, int levels, int internalFormat, int width, int height);
public abstract void texStorage3D(int target, int levels, int internalFormat, int width, int height, int depth);
public abstract void textureStorage1D(int texture, int levels, int internalFormat, int width);
public abstract void textureStorage2D(int texture, int levels, int internalFormat, int width, int height);
public abstract void textureStorage3D(int texture, int levels, int internalFormat, int width, int height, int depth);
public abstract void generateTextureMipmap(int texture);
public abstract void textureImage2DEXT(int texture, int target, int level, int internalformat, int width, int height, int border, int format, int type, ByteBuffer pixels);
public abstract void textureImage2DEXT(int texture, int target, int level, int internalformat, int width, int height, int border, int format, int type, IntBuffer pixels);
@@ -138,19 +138,4 @@ public class DSAARB extends DSAUnsupported {
public int createTexture(int target) {
return RENDER_BACKEND.createTextures(target);
}
@Override
public void textureStorage1D(int texture, int target, int levels, int internalFormat, int width) {
RENDER_BACKEND.textureStorage1D(texture, levels, internalFormat, width);
}
@Override
public void textureStorage2D(int texture, int target, int levels, int internalFormat, int width, int height) {
RENDER_BACKEND.textureStorage2D(texture, levels, internalFormat, width, height);
}
@Override
public void textureStorage3D(int texture, int target, int levels, int internalFormat, int width, int height, int depth) {
RENDER_BACKEND.textureStorage3D(texture, levels, internalFormat, width, height, depth);
}
}
@@ -40,9 +40,4 @@ public interface DSAAccess {
int createFramebuffer();
int createTexture(int target);
// Texture storage methods for custom images
void textureStorage1D(int texture, int target, int levels, int internalFormat, int width);
void textureStorage2D(int texture, int target, int levels, int internalFormat, int width, int height);
void textureStorage3D(int texture, int target, int levels, int internalFormat, int width, int height, int depth);
}
@@ -1,6 +1,7 @@
package com.gtnewhorizons.angelica.glsm.dsa;
import com.gtnewhorizons.angelica.glsm.GLStateManager;
import com.gtnewhorizons.angelica.glsm.stacks.TextureBindingStack;
import org.lwjgl.opengl.GL11;
import static com.gtnewhorizons.angelica.glsm.backend.BackendManager.RENDER_BACKEND;
@@ -23,16 +24,15 @@ public class DSAUnsupported implements DSAAccess {
@Override
public void textureImage2D(int texture, int target, int level, int internalformat, int width, int height, int border, int format, int type, ByteBuffer pixels) {
// Get what cache thinks is bound - we'll restore to this to keep cache/GL in sync
final int cachedBinding = GLStateManager.getBoundTextureForServerState();
final int cachedBinding = previousBinding(target);
RENDER_BACKEND.bindTexture(target, texture);
RENDER_BACKEND.texImage2D(target, level, internalformat, width, height, border, format, type, pixels);
RENDER_BACKEND.bindTexture(target, cachedBinding); // Restore to cache value
RENDER_BACKEND.bindTexture(target, cachedBinding);
}
@Override
public void textureImage2D(int texture, int target, int level, int internalformat, int width, int height, int border, int format, int type, IntBuffer pixels) {
final int cachedBinding = GLStateManager.getBoundTextureForServerState();
final int cachedBinding = previousBinding(target);
RENDER_BACKEND.bindTexture(target, texture);
RENDER_BACKEND.texImage2D(target, level, internalformat, width, height, border, format, type, pixels);
RENDER_BACKEND.bindTexture(target, cachedBinding);
@@ -40,7 +40,7 @@ public class DSAUnsupported implements DSAAccess {
@Override
public void textureSubImage2D(int texture, int target, int level, int xoffset, int yoffset, int width, int height, int format, int type, ByteBuffer pixels) {
final int cachedBinding = GLStateManager.getBoundTextureForServerState();
final int cachedBinding = previousBinding(target);
RENDER_BACKEND.bindTexture(target, texture);
RENDER_BACKEND.texSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels);
RENDER_BACKEND.bindTexture(target, cachedBinding);
@@ -48,7 +48,7 @@ public class DSAUnsupported implements DSAAccess {
@Override
public void textureSubImage2D(int texture, int target, int level, int xoffset, int yoffset, int width, int height, int format, int type, IntBuffer pixels) {
final int cachedBinding = GLStateManager.getBoundTextureForServerState();
final int cachedBinding = previousBinding(target);
RENDER_BACKEND.bindTexture(target, texture);
RENDER_BACKEND.texSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels);
RENDER_BACKEND.bindTexture(target, cachedBinding);
@@ -56,20 +56,23 @@ public class DSAUnsupported implements DSAAccess {
@Override
public void texParameteri(int texture, int target, int pname, int param) {
GLStateManager.glBindTexture(GL11.GL_TEXTURE_2D, texture);
final int previous = bindForEdit(target, texture);
GLStateManager.glTexParameteri(target, pname, param);
restoreBinding(target, previous);
}
@Override
public void texParameterf(int texture, int target, int pname, float param) {
GLStateManager.glBindTexture(GL11.GL_TEXTURE_2D, texture);
final int previous = bindForEdit(target, texture);
GLStateManager.glTexParameterf(target, pname, param);
restoreBinding(target, previous);
}
@Override
public void texParameteriv(int texture, int target, int pname, IntBuffer params) {
GLStateManager.glBindTexture(GL11.GL_TEXTURE_2D, texture);
final int previous = bindForEdit(target, texture);
GLStateManager.glTexParameter(target, pname, params);
restoreBinding(target, previous);
}
@Override
@@ -86,19 +89,23 @@ public class DSAUnsupported implements DSAAccess {
@Override
public int getTexParameteri(int texture, int target, int pname) {
GLStateManager.glBindTexture(GL11.GL_TEXTURE_2D, texture);
return GLStateManager.glGetTexParameteri(target, pname);
final int previous = bindForEdit(target, texture);
final int result = GLStateManager.glGetTexParameteri(target, pname);
restoreBinding(target, previous);
return result;
}
@Override
public float getTexParameterf(int texture, int target, int pname) {
GLStateManager.glBindTexture(GL11.GL_TEXTURE_2D, texture);
return GLStateManager.glGetTexParameterf(target, pname);
final int previous = bindForEdit(target, texture);
final float result = GLStateManager.glGetTexParameterf(target, pname);
restoreBinding(target, previous);
return result;
}
@Override
public int getTexLevelParameteri(int texture, int level, int pname) {
final int previous = GLStateManager.getBoundTextureForServerState();
final int previous = previous2D();
RENDER_BACKEND.bindTexture(GL11.GL_TEXTURE_2D, texture);
final int result = RENDER_BACKEND.getTexLevelParameteri(GL11.GL_TEXTURE_2D, level, pname);
RENDER_BACKEND.bindTexture(GL11.GL_TEXTURE_2D, previous);
@@ -107,7 +114,7 @@ public class DSAUnsupported implements DSAAccess {
@Override
public void copyTexSubImage2D(int destTexture, int target, int i, int i1, int i2, int i3, int i4, int width, int height) {
final int previous = GLStateManager.getBoundTextureForServerState();
final int previous = previous2D();
GLStateManager.glBindTexture(GL11.GL_TEXTURE_2D, destTexture);
RENDER_BACKEND.copyTexSubImage2D(target, i, i1, i2, i3, i4, width, height);
GLStateManager.glBindTexture(GL11.GL_TEXTURE_2D, previous);
@@ -163,27 +170,39 @@ public class DSAUnsupported implements DSAAccess {
return texture;
}
@Override
public void textureStorage1D(int texture, int target, int levels, int internalFormat, int width) {
final int previous = RENDER_BACKEND.getInteger(GL11.GL_TEXTURE_BINDING_1D);
RENDER_BACKEND.bindTexture(target, texture);
RENDER_BACKEND.texStorage1D(target, levels, internalFormat, width);
RENDER_BACKEND.bindTexture(target, previous);
private static int bindingQuery(int target) {
return switch (target) {
case GL11.GL_TEXTURE_1D -> GL11.GL_TEXTURE_BINDING_1D;
case GL12.GL_TEXTURE_3D -> GL12.GL_TEXTURE_BINDING_3D;
case GL13.GL_TEXTURE_CUBE_MAP -> GL13.GL_TEXTURE_BINDING_CUBE_MAP;
case GL30.GL_TEXTURE_2D_ARRAY -> GL30.GL_TEXTURE_BINDING_2D_ARRAY;
case GL31.GL_TEXTURE_RECTANGLE -> GL31.GL_TEXTURE_BINDING_RECTANGLE;
default -> GL11.GL_TEXTURE_BINDING_2D;
};
}
@Override
public void textureStorage2D(int texture, int target, int levels, int internalFormat, int width, int height) {
final int previous = (target == GL11.GL_TEXTURE_2D) ? GLStateManager.getBoundTextureForServerState() : RENDER_BACKEND.getInteger(GL31.GL_TEXTURE_BINDING_RECTANGLE);
RENDER_BACKEND.bindTexture(target, texture);
RENDER_BACKEND.texStorage2D(target, levels, internalFormat, width, height);
RENDER_BACKEND.bindTexture(target, previous);
private static int previousBinding(int target) {
return target == GL11.GL_TEXTURE_2D ? previous2D() : RENDER_BACKEND.getInteger(bindingQuery(target));
}
@Override
public void textureStorage3D(int texture, int target, int levels, int internalFormat, int width, int height, int depth) {
final int previous = RENDER_BACKEND.getInteger(GL12.GL_TEXTURE_BINDING_3D);
RENDER_BACKEND.bindTexture(target, texture);
RENDER_BACKEND.texStorage3D(target, levels, internalFormat, width, height, depth);
RENDER_BACKEND.bindTexture(target, previous);
private static int previous2D() {
if (GLStateManager.isCachingEnabled()) {
final TextureBindingStack slot = GLStateManager.getTextures().getTextureUnitBindings(GLStateManager.getActiveTextureUnit());
final int t = slot.getTarget();
if (t == 0 || t == GL11.GL_TEXTURE_2D) return slot.getBinding();
}
return RENDER_BACKEND.getInteger(GL11.GL_TEXTURE_BINDING_2D);
}
private static int bindForEdit(int target, int texture) {
final int previous = previousBinding(target);
if (target == GL11.GL_TEXTURE_2D) GLStateManager.glBindTexture(target, texture);
else RENDER_BACKEND.bindTexture(target, texture);
return previous;
}
private static void restoreBinding(int target, int previous) {
if (target == GL11.GL_TEXTURE_2D) GLStateManager.glBindTexture(target, previous);
else RENDER_BACKEND.bindTexture(target, previous);
}
}
@@ -0,0 +1,96 @@
package com.gtnewhorizons.angelica.glsm.dsa;
import com.gtnewhorizons.angelica.glsm.GLCoreTest;
import com.gtnewhorizons.angelica.glsm.GLStateManager;
import org.junit.jupiter.api.Test;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL12;
import org.lwjgl.opengl.GL13;
import java.nio.ByteBuffer;
import static org.junit.jupiter.api.Assertions.assertEquals;
@GLCoreTest
public class DSAUnsupportedBindingTest {
private final DSAUnsupported dsa = new DSAUnsupported();
@Test
void nonTwoDParameterEditsRestoreTheTargetBinding() {
final int a = GLStateManager.glGenTextures();
final int c = GL11.glGenTextures();
final int d = GL11.glGenTextures();
try {
GLStateManager.glBindTexture(GL11.GL_TEXTURE_2D, a);
for (int tex : new int[] { c, d }) {
GL11.glBindTexture(GL13.GL_TEXTURE_CUBE_MAP, tex);
for (int i = 0; i < 6; i++) {
GL11.glTexImage2D(GL13.GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL11.GL_RGBA8, 1, 1, 0, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, (ByteBuffer) null);
}
}
dsa.texParameteri(c, GL13.GL_TEXTURE_CUBE_MAP, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_NEAREST);
assertEquals(GL11.GL_NEAREST, dsa.getTexParameteri(c, GL13.GL_TEXTURE_CUBE_MAP, GL11.GL_TEXTURE_MIN_FILTER));
assertEquals(d, GL11.glGetInteger(GL13.GL_TEXTURE_BINDING_CUBE_MAP));
assertEquals(a, GL11.glGetInteger(GL11.GL_TEXTURE_BINDING_2D));
} finally {
GL11.glBindTexture(GL13.GL_TEXTURE_CUBE_MAP, 0);
GL11.glDeleteTextures(c);
GL11.glDeleteTextures(d);
GLStateManager.glDeleteTextures(a);
}
}
@Test
void twoDParameterEditRestoresTheCachedBinding() {
final int a = GLStateManager.glGenTextures();
final int b = GLStateManager.glGenTextures();
try {
GLStateManager.glBindTexture(GL11.GL_TEXTURE_2D, a);
dsa.texParameteri(b, GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_NEAREST);
assertEquals(a, GLStateManager.getBoundTextureForServerState());
assertEquals(a, GL11.glGetInteger(GL11.GL_TEXTURE_BINDING_2D));
GL11.glBindTexture(GL11.GL_TEXTURE_2D, b);
assertEquals(GL11.GL_NEAREST, GL11.glGetTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER));
GL11.glBindTexture(GL11.GL_TEXTURE_2D, a);
} finally {
GLStateManager.glDeleteTextures(a);
GLStateManager.glDeleteTextures(b);
}
}
@Test
void twoDEditWithANonTwoDTextureBoundRestoresTheDriverTwoDBinding() {
final int y = GLStateManager.glGenTextures();
final int t = GLStateManager.glGenTextures();
final int x = GL11.glGenTextures();
try {
GLStateManager.glActiveTexture(GL13.GL_TEXTURE3);
GLStateManager.glBindTexture(GL11.GL_TEXTURE_2D, t);
GLStateManager.glBindTexture(GL11.GL_TEXTURE_2D, y);
GLStateManager.glBindTexture(GL12.GL_TEXTURE_3D, x);
while (GL11.glGetError() != GL11.GL_NO_ERROR) {
}
dsa.texParameteri(t, GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_NEAREST);
assertEquals(GL11.GL_NO_ERROR, GL11.glGetError());
assertEquals(y, GL11.glGetInteger(GL11.GL_TEXTURE_BINDING_2D));
assertEquals(x, GL11.glGetInteger(GL12.GL_TEXTURE_BINDING_3D));
assertEquals(y, GLStateManager.getBoundTextureForServerState());
GL11.glBindTexture(GL11.GL_TEXTURE_2D, t);
assertEquals(GL11.GL_NEAREST, GL11.glGetTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER));
GL11.glBindTexture(GL11.GL_TEXTURE_2D, y);
} finally {
GL11.glBindTexture(GL12.GL_TEXTURE_3D, 0);
GLStateManager.glBindTexture(GL11.GL_TEXTURE_2D, 0);
GLStateManager.glActiveTexture(GL13.GL_TEXTURE0);
GLStateManager.glDeleteTextures(y);
GLStateManager.glDeleteTextures(t);
GL11.glDeleteTextures(x);
}
}
}
@@ -1449,31 +1449,6 @@ public final class Lwjgl3GLRenderBackend extends RenderBackend {
GL42C.glTexStorage2D(target, levels, internalFormat, width, height);
}
@Override
public void textureStorage2D(int texture, int levels, int internalFormat, int width, int height) {
GL45C.glTextureStorage2D(texture, levels, internalFormat, width, height);
}
@Override
public void texStorage1D(int target, int levels, int internalFormat, int width) {
GL42C.glTexStorage1D(target, levels, internalFormat, width);
}
@Override
public void texStorage3D(int target, int levels, int internalFormat, int width, int height, int depth) {
GL42C.glTexStorage3D(target, levels, internalFormat, width, height, depth);
}
@Override
public void textureStorage1D(int texture, int levels, int internalFormat, int width) {
GL45C.glTextureStorage1D(texture, levels, internalFormat, width);
}
@Override
public void textureStorage3D(int texture, int levels, int internalFormat, int width, int height, int depth) {
GL45C.glTextureStorage3D(texture, levels, internalFormat, width, height, depth);
}
@Override
public void generateTextureMipmap(int texture) {
GL45C.glGenerateTextureMipmap(texture);
@@ -3628,14 +3628,6 @@ public class SDLGPURenderBackend extends RenderBackend {
@Override public void textureParameteriv(int texture, int target, int pname, IntBuffer params) {
if (params.remaining() > 0) textureParameteri(texture, target, pname, params.get(params.position()));
}
@Override public void texStorage1D(int target, int levels, int internalFormat, int width) {
final ContextState st = s();
if (isProxyTarget(target)) {
recordProxyTexImage(st, target, 0, internalFormat, width, 1, 1);
return;
}
texStorageImpl(st, st.boundTextures[st.activeTextureUnit], target, internalFormat, width, 1, 1, levels);
}
@Override public void texStorage2D(int target, int levels, int internalFormat, int width, int height) {
final ContextState st = s();
if (isProxyTarget(target)) {
@@ -3644,23 +3636,6 @@ public class SDLGPURenderBackend extends RenderBackend {
}
texStorageImpl(st, st.boundTextures[st.activeTextureUnit], target, internalFormat, width, height, 1, levels);
}
@Override public void texStorage3D(int target, int levels, int internalFormat, int width, int height, int depth) {
final ContextState st = s();
if (isProxyTarget(target)) {
recordProxyTexImage(st, target, 0, internalFormat, width, height, depth);
return;
}
texStorageImpl(st, st.boundTextures[st.activeTextureUnit], target, internalFormat, width, height, depth, levels);
}
@Override public void textureStorage1D(int texture, int levels, int internalFormat, int width) {
texStorageImpl(s(), texture, GL11.GL_TEXTURE_2D, internalFormat, width, 1, 1, levels);
}
@Override public void textureStorage2D(int texture, int levels, int internalFormat, int width, int height) {
texStorageImpl(s(), texture, GL11.GL_TEXTURE_2D, internalFormat, width, height, 1, levels);
}
@Override public void textureStorage3D(int texture, int levels, int internalFormat, int width, int height, int depth) {
texStorageImpl(s(), texture, GL11.GL_TEXTURE_2D, internalFormat, width, height, depth, levels);
}
private void texStorageImpl(ContextState st, int glId, int target, int internalFormat, int w, int h, int d, int levels) {
if (glId == 0) return;
@@ -3982,7 +3957,7 @@ public class SDLGPURenderBackend extends RenderBackend {
case GL43.GL_MAX_DEBUG_MESSAGE_LENGTH -> 1024;
case GL11.GL_DRAW_BUFFER -> drawBufferEnum(cs.boundFboId, cs.defaultFboId);
case GL11.GL_READ_BUFFER -> readBufferEnum(cs.boundReadFboId, cs.defaultFboId);
case GL11.GL_TEXTURE_BINDING_2D -> boundTextureOf(cs.activeTextureUnit, cs.boundTextures);
case GL11.GL_TEXTURE_BINDING_2D, GL11.GL_TEXTURE_BINDING_1D, GL12.GL_TEXTURE_BINDING_3D, GL13.GL_TEXTURE_BINDING_CUBE_MAP, GL30.GL_TEXTURE_BINDING_1D_ARRAY, GL30.GL_TEXTURE_BINDING_2D_ARRAY, GL31.GL_TEXTURE_BINDING_RECTANGLE, GL40.GL_TEXTURE_BINDING_CUBE_MAP_ARRAY -> boundTextureOf(cs.activeTextureUnit, cs.boundTextures);
case GL11.GL_DEPTH_BITS -> getFramebufferAttachmentParameteri(GL30.GL_DRAW_FRAMEBUFFER, GL11.GL_DEPTH, GL30.GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE);
case GL11.GL_STENCIL_BITS -> getFramebufferAttachmentParameteri(GL30.GL_DRAW_FRAMEBUFFER, GL11.GL_STENCIL, GL30.GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE);
case GL11.GL_PACK_ALIGNMENT -> cs.pixelStore.packAlignment;
@@ -0,0 +1,47 @@
package com.gtnewhorizons.angelica.sdlgpu.glsm;
import com.gtnewhorizons.angelica.glsm.GLStateManager;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL12;
import org.lwjgl.opengl.GL13;
import org.lwjgl.opengl.GL30;
import org.lwjgl.opengl.GL31;
import org.lwjgl.opengl.GL40;
import static com.gtnewhorizons.angelica.glsm.backend.BackendManager.RENDER_BACKEND;
import static org.junit.jupiter.api.Assertions.assertEquals;
@Tag("glsm-sdl")
@ExtendWith(GlsmSdlFrameExtension.class)
class GlsmSdlTextureBindingQueryTest {
@BeforeAll
static void boot() {
GlsmSdlHeadlessRig.boot();
}
@Test
void everyBindingQueryReadsThePerUnitSlot() {
GLStateManager.glActiveTexture(GL13.GL_TEXTURE3);
final int tex = GLStateManager.glGenTextures();
try {
GLStateManager.glBindTexture(GL12.GL_TEXTURE_3D, tex);
assertEquals(tex, RENDER_BACKEND.getInteger(GL11.GL_TEXTURE_BINDING_2D), "GL_TEXTURE_BINDING_2D");
assertEquals(tex, RENDER_BACKEND.getInteger(GL11.GL_TEXTURE_BINDING_1D), "GL_TEXTURE_BINDING_1D");
assertEquals(tex, RENDER_BACKEND.getInteger(GL12.GL_TEXTURE_BINDING_3D), "GL_TEXTURE_BINDING_3D");
assertEquals(tex, RENDER_BACKEND.getInteger(GL13.GL_TEXTURE_BINDING_CUBE_MAP), "GL_TEXTURE_BINDING_CUBE_MAP");
assertEquals(tex, RENDER_BACKEND.getInteger(GL30.GL_TEXTURE_BINDING_1D_ARRAY), "GL_TEXTURE_BINDING_1D_ARRAY");
assertEquals(tex, RENDER_BACKEND.getInteger(GL30.GL_TEXTURE_BINDING_2D_ARRAY), "GL_TEXTURE_BINDING_2D_ARRAY");
assertEquals(tex, RENDER_BACKEND.getInteger(GL31.GL_TEXTURE_BINDING_RECTANGLE), "GL_TEXTURE_BINDING_RECTANGLE");
assertEquals(tex, RENDER_BACKEND.getInteger(GL40.GL_TEXTURE_BINDING_CUBE_MAP_ARRAY), "GL_TEXTURE_BINDING_CUBE_MAP_ARRAY");
} finally {
GLStateManager.glBindTexture(GL12.GL_TEXTURE_3D, 0);
GLStateManager.glActiveTexture(GL13.GL_TEXTURE0);
GLStateManager.glDeleteTextures(tex);
}
}
}
@@ -2,6 +2,7 @@ package com.gtnewhorizons.angelica.client.rendering;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import net.coderbot.iris.gl.state.MultiListenerNotifier;
import net.coderbot.iris.gl.state.StateUpdateNotifiers;
import net.minecraft.client.renderer.texture.AbstractTexture;
import org.jetbrains.annotations.Nullable;
@@ -13,13 +14,13 @@ public class TextureTracker {
*/
public static final TextureTracker INSTANCE = new TextureTracker();
private static Runnable bindTextureListener;
private static final MultiListenerNotifier bindTextureNotifier = new MultiListenerNotifier();
static {
StateUpdateNotifiers.bindTextureNotifier = listener -> bindTextureListener = listener;
StateUpdateNotifiers.bindTextureNotifier = bindTextureNotifier;
}
private final Int2ObjectMap<AbstractTexture> textures = new Int2ObjectOpenHashMap<>();
private TextureTracker() {
@@ -33,11 +34,9 @@ public class TextureTracker {
public AbstractTexture getTexture(int id) {
return textures.get(id);
}
public void onBindTexture() {
if (bindTextureListener != null) {
bindTextureListener.run();
}
bindTextureNotifier.run();
}
public void onDeleteTexture(int id) {
@@ -19,6 +19,7 @@ import net.coderbot.iris.gl.blending.BlendModeStorage;
import net.coderbot.iris.gl.blending.DepthColorStorage;
import net.coderbot.iris.gl.program.ProgramUniforms;
import net.coderbot.iris.gl.program.Program;
import net.coderbot.iris.gl.state.MultiListenerNotifier;
import net.coderbot.iris.gl.state.StateUpdateNotifiers;
import net.coderbot.iris.pipeline.DeferredWorldRenderingPipeline;
import net.coderbot.iris.pipeline.WorldRenderingPipeline;
@@ -30,8 +31,8 @@ import org.lwjgl.opengl.GL11;
public class IrisGLSMBridge {
private static final MultiListenerNotifier alphaTestNotifier = new MultiListenerNotifier();
private static Runnable alphaFuncListener = null;
private static Runnable alphaTestListener = null;
private static Runnable blendFuncListener = null;
private static Runnable fogModeListener = null;
private static Runnable fogStartListener = null;
@@ -51,8 +52,8 @@ public class IrisGLSMBridge {
static {
programLastUpdatedFrame.defaultReturnValue(-1);
StateUpdateNotifiers.alphaTestNotifier = alphaTestNotifier;
StateUpdateNotifiers.alphaFuncNotifier = listener -> alphaFuncListener = listener;
StateUpdateNotifiers.alphaTestNotifier = listener -> alphaTestListener = listener;
StateUpdateNotifiers.blendFuncNotifier = listener -> blendFuncListener = listener;
StateUpdateNotifiers.fogModeNotifier = listener -> fogModeListener = listener;
StateUpdateNotifiers.fogStartNotifier = listener -> fogStartListener = listener;
@@ -173,7 +174,7 @@ public class IrisGLSMBridge {
GLSMHooks.ALPHA_STATE_CHANGE.addListener(event -> {
if (Iris.enabled) {
if (alphaFuncListener != null) alphaFuncListener.run();
if (alphaTestListener != null) alphaTestListener.run();
alphaTestNotifier.run();
}
});
@@ -613,6 +613,7 @@ public enum Mixins implements IMixins {
.setPhase(Phase.EARLY)
.addExcludedMod(TargetedMod.ARCHAICFIX)
.addExcludedMod(TargetedMod.SUPERNOVA)
.addExcludedMod(TargetedMod.LUMI)
.setApplyIf(() -> AngelicaConfig.optimizeWorldUpdateLight)
.addCommonMixins("angelica.lighting.MixinWorld_FixLightUpdateLag")),
@@ -988,27 +989,6 @@ public enum Mixins implements IMixins {
"MixinRenderGlobal"
))
),
MCPATCHER_FORGE_CC_NO_CTM(new MixinBuilder("MCP:F Custom Colors, no Connected Textures")
.setPhase(Phase.EARLY)
.setApplyIf(() -> AngelicaConfig.enableMCPatcherForgeFeatures
&& !MCPatcherForgeConfig.ConnectedTextures.enabled
&& MCPatcherForgeConfig.CustomColors.enabled)
.addClientMixins("mcpatcherforge.ctm_cc.MixinRenderBlocksNoCTM")
),
MCPATCHER_FORGE_CTM_NO_CC(new MixinBuilder("MCP:F Connected Textures, no Custom Colours")
.setPhase(Phase.EARLY)
.setApplyIf(() -> AngelicaConfig.enableMCPatcherForgeFeatures
&& MCPatcherForgeConfig.ConnectedTextures.enabled
&& !MCPatcherForgeConfig.CustomColors.enabled)
.addClientMixins("mcpatcherforge.ctm_cc.MixinRenderBlocksNoCC")
),
MCPATCHER_FORGE_CTM_AND_CC(new MixinBuilder("MCP:F Connected Textures and Custom Colors")
.setPhase(Phase.EARLY)
.setApplyIf(() -> AngelicaConfig.enableMCPatcherForgeFeatures
&& MCPatcherForgeConfig.ConnectedTextures.enabled
&& MCPatcherForgeConfig.CustomColors.enabled)
.addClientMixins("mcpatcherforge.ctm_cc.MixinRenderBlocks")
),
MCPATCHER_FORGE_CTM_OR_CC(new MixinBuilder("MCP:F Connected Textures or Custom Colors")
.setPhase(Phase.EARLY)
.setApplyIf(() -> AngelicaConfig.enableMCPatcherForgeFeatures
@@ -21,6 +21,7 @@ public enum TargetedMod implements ITargetMod {
EXTRAUTILS(null, "ExtraUtilities"),
FARSEEK("farseek.core.FarseekCoreMod", "farseek"),
FALSETWEAKS("com.falsepattern.falsetweaks.asm.CoreLoadingPlugin", "falsetweaks"),
LUMI("com.falsepattern.lumi.internal.asm.ASMLoadingPlugin", "lumi"),
MINEFACTORY_RELOADED(null, "MineFactoryReloaded"),
NTM_SPACE("com.hbm.dim.SolarSystem"),
IC2("ic2.core.coremod.IC2core", "IC2"),
@@ -427,6 +427,11 @@ public class ColorizeBlock {
}
}
public static float[] getRedstoneWireColor(int meta) {
float[][] rc = redstoneColor;
return rc == null ? null : rc[meta & 0xf];
}
public static int colorizeRedstoneWire(IBlockAccess blockAccess, int x, int y, int z, int defaultColor) {
if (redstoneColor == null) {
return defaultColor;
@@ -76,7 +76,7 @@ public class ProgramUniforms {
hasDeferredUploads = true;
return;
}
if (active != null) {
if (active != null && active != this) {
active.removeListeners();
}
@@ -0,0 +1,29 @@
package net.coderbot.iris.gl.state;
import java.util.Arrays;
public final class MultiListenerNotifier implements ValueUpdateNotifier {
private Runnable[] listeners = new Runnable[4];
private int count;
@Override
public void setListener(Runnable listener) {
if (listener == null) {
count = 0;
return;
}
for (int i = 0; i < count; i++) {
if (listeners[i] == listener) return;
}
if (count == listeners.length) listeners = Arrays.copyOf(listeners, count << 1);
listeners[count++] = listener;
}
public void run() {
final Runnable[] l = listeners;
for (int i = 0, n = count; i < n; i++) {
l[i].run();
}
}
}
@@ -13,18 +13,13 @@ import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Constant;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.ModifyArgs;
import org.spongepowered.asm.mixin.injection.ModifyConstant;
import org.spongepowered.asm.mixin.injection.ModifyVariable;
import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import org.spongepowered.asm.mixin.injection.invoke.arg.Args;
import com.llamalad7.mixinextras.injector.v2.WrapWithCondition;
import com.llamalad7.mixinextras.sugar.Share;
import com.llamalad7.mixinextras.sugar.ref.LocalBooleanRef;
import com.llamalad7.mixinextras.sugar.Local;
import com.llamalad7.mixinextras.sugar.ref.LocalFloatRef;
import com.prupe.mcpatcher.cc.ColorizeBlock;
import com.prupe.mcpatcher.cc.Colorizer;
import com.prupe.mcpatcher.mal.block.RenderBlocksUtils;
@@ -99,96 +94,70 @@ public abstract class MixinRenderBlocks {
Tessellator.instance.setColorOpaque_F(Colorizer.setColor[0], Colorizer.setColor[1], Colorizer.setColor[2]);
}
@Inject(method = "renderBlockRedstoneWire(Lnet/minecraft/block/Block;III)Z", at = @At("HEAD"))
private void calculateComputeRedstoneWireColor(Block block, int x, int y, int z,
CallbackInfoReturnable<Boolean> cir,
@Share("computeRedstoneWireColor") LocalBooleanRef computeRedstoneWireColor, @Share("red") LocalFloatRef red,
@Share("green") LocalFloatRef green, @Share("blue") LocalFloatRef blue) {
computeRedstoneWireColor
.set(ColorizeBlock.computeRedstoneWireColor(this.blockAccess.getBlockMetadata(x, y, z)));
red.set(Math.max(Colorizer.setColor[0], 0.0f));
green.set(Math.max(Colorizer.setColor[1], 0.0f));
blue.set(Math.max(Colorizer.setColor[2], 0.0f));
@Unique
private void mcpatcherforge$redirectRedstoneWireColor(Tessellator tessellator, float red, float green,
float blue, Block block, int x, int y, int z) {
float[] c = ColorizeBlock.getRedstoneWireColor(this.blockAccess.getBlockMetadata(x, y, z));
if (c != null) {
tessellator.setColorOpaque_F(Math.max(c[0], 0.0f), Math.max(c[1], 0.0f), Math.max(c[2], 0.0f));
} else {
tessellator.setColorOpaque_F(red, green, blue);
}
}
@ModifyArgs(
@Redirect(
method = "renderBlockRedstoneWire(Lnet/minecraft/block/Block;III)Z",
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/client/renderer/Tessellator;setColorOpaque_F(FFF)V",
ordinal = 0))
private void modifyColorRedstoneWire1(Args args,
@Share("computeRedstoneWireColor") LocalBooleanRef computeRedstoneWireColor, @Share("red") LocalFloatRef red,
@Share("green") LocalFloatRef green, @Share("blue") LocalFloatRef blue) {
if (computeRedstoneWireColor.get()) {
args.set(0, red.get());
args.set(1, green.get());
args.set(2, blue.get());
}
private void modifyColorRedstoneWire1(Tessellator tessellator, float red, float green, float blue, Block block,
int x, int y, int z) {
mcpatcherforge$redirectRedstoneWireColor(tessellator, red, green, blue, block, x, y, z);
}
@ModifyArgs(
@Redirect(
method = "renderBlockRedstoneWire(Lnet/minecraft/block/Block;III)Z",
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/client/renderer/Tessellator;setColorOpaque_F(FFF)V",
ordinal = 4))
private void modifyColorRedstoneWire2(Args args,
@Share("computeRedstoneWireColor") LocalBooleanRef computeRedstoneWireColor, @Share("red") LocalFloatRef red,
@Share("green") LocalFloatRef green, @Share("blue") LocalFloatRef blue) {
if (computeRedstoneWireColor.get()) {
args.set(0, red.get());
args.set(1, green.get());
args.set(2, blue.get());
}
private void modifyColorRedstoneWire2(Tessellator tessellator, float red, float green, float blue, Block block,
int x, int y, int z) {
mcpatcherforge$redirectRedstoneWireColor(tessellator, red, green, blue, block, x, y, z);
}
@ModifyArgs(
@Redirect(
method = "renderBlockRedstoneWire(Lnet/minecraft/block/Block;III)Z",
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/client/renderer/Tessellator;setColorOpaque_F(FFF)V",
ordinal = 6))
private void modifyColorRedstoneWire3(Args args,
@Share("computeRedstoneWireColor") LocalBooleanRef computeRedstoneWireColor, @Share("red") LocalFloatRef red,
@Share("green") LocalFloatRef green, @Share("blue") LocalFloatRef blue) {
if (computeRedstoneWireColor.get()) {
args.set(0, red.get());
args.set(1, green.get());
args.set(2, blue.get());
}
private void modifyColorRedstoneWire3(Tessellator tessellator, float red, float green, float blue, Block block,
int x, int y, int z) {
mcpatcherforge$redirectRedstoneWireColor(tessellator, red, green, blue, block, x, y, z);
}
@ModifyArgs(
@Redirect(
method = "renderBlockRedstoneWire(Lnet/minecraft/block/Block;III)Z",
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/client/renderer/Tessellator;setColorOpaque_F(FFF)V",
ordinal = 8))
private void modifyColorRedstoneWire4(Args args,
@Share("computeRedstoneWireColor") LocalBooleanRef computeRedstoneWireColor, @Share("red") LocalFloatRef red,
@Share("green") LocalFloatRef green, @Share("blue") LocalFloatRef blue) {
if (computeRedstoneWireColor.get()) {
args.set(0, red.get());
args.set(1, green.get());
args.set(2, blue.get());
}
private void modifyColorRedstoneWire4(Tessellator tessellator, float red, float green, float blue, Block block,
int x, int y, int z) {
mcpatcherforge$redirectRedstoneWireColor(tessellator, red, green, blue, block, x, y, z);
}
@ModifyArgs(
@Redirect(
method = "renderBlockRedstoneWire(Lnet/minecraft/block/Block;III)Z",
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/client/renderer/Tessellator;setColorOpaque_F(FFF)V",
ordinal = 10))
private void modifyColorRedstoneWire5(Args args,
@Share("computeRedstoneWireColor") LocalBooleanRef computeRedstoneWireColor, @Share("red") LocalFloatRef red,
@Share("green") LocalFloatRef green, @Share("blue") LocalFloatRef blue) {
if (computeRedstoneWireColor.get()) {
args.set(0, red.get());
args.set(1, green.get());
args.set(2, blue.get());
}
private void modifyColorRedstoneWire5(Tessellator tessellator, float red, float green, float blue, Block block,
int x, int y, int z) {
mcpatcherforge$redirectRedstoneWireColor(tessellator, red, green, blue, block, x, y, z);
}
@Inject(
@@ -454,6 +423,37 @@ public abstract class MixinRenderBlocks {
}
}
@Redirect(
method = "renderBlockLiquid(Lnet/minecraft/block/Block;III)Z",
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/client/renderer/Tessellator;setColorOpaque_F(FFF)V",
ordinal = 2))
private void mcpatcherforge$redirectColor10(Tessellator tessellator, float red, float green, float blue,
Block block, int x, int y, int z, @Local(name = "k1") int k1) {
if (!(ColorizeBlock.isSmooth = ColorizeBlock
.setupBlockSmoothing((RenderBlocks) (Object) this, block, this.blockAccess, x, y, z, k1 + 8))) {
tessellator.setColorOpaque_F(red, green, blue);
}
}
@Redirect(
method = "renderBlockLiquid(Lnet/minecraft/block/Block;III)Z",
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/client/renderer/Tessellator;setColorOpaque_F(FFF)V",
ordinal = 1))
private void mcpatcherforge$redirectColor9(Tessellator tessellator, float red, float green, float blue, Block block,
int x, int y, int z, @Local(name = "f") float f, @Local(name = "f1") float f1, @Local(name = "f2") float f2) {
if (!(ColorizeBlock.isSmooth = ColorizeBlock
.setupBlockSmoothing((RenderBlocks) (Object) this, block, this.blockAccess, x, y, z, 6))) {
tessellator.setColorOpaque_F(red * f, green * f1, blue * f2);
}
if (ColorizeBlock.isSmooth) {
this.enableAO = true;
}
}
// Violate DRY
@Redirect(
@@ -1040,4 +1040,28 @@ public abstract class MixinRenderBlocks {
return getBlockIcon(block, blockAccess, x, y, z, side);
}
@Redirect(
method = "renderBlockLiquid(Lnet/minecraft/block/Block;III)Z",
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/client/renderer/RenderBlocks;getBlockIconFromSideAndMetadata(Lnet/minecraft/block/Block;II)Lnet/minecraft/util/IIcon;",
ordinal = 0))
private IIcon mcpatcherforge$liquidTopIcon(RenderBlocks instance, Block block, int side, int meta,
Block specializedBlock, int x, int y, int z) {
return (this.blockAccess == null) ? this.getBlockIconFromSideAndMetadata(block, side, meta)
: this.getBlockIcon(block, this.blockAccess, x, y, z, side);
}
@Redirect(
method = "renderBlockLiquid(Lnet/minecraft/block/Block;III)Z",
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/client/renderer/RenderBlocks;getBlockIconFromSideAndMetadata(Lnet/minecraft/block/Block;II)Lnet/minecraft/util/IIcon;",
ordinal = 2))
private IIcon mcpatcherforge$liquidSideIcon(RenderBlocks instance, Block block, int side, int meta,
Block specializedBlock, int x, int y, int z) {
return (this.blockAccess == null) ? this.getBlockIconFromSideAndMetadata(block, side, meta)
: this.getBlockIcon(block, this.blockAccess, x, y, z, side);
}
}
@@ -1,106 +0,0 @@
package com.gtnewhorizons.angelica.mixins.early.mcpatcherforge.ctm_cc;
import net.minecraft.block.Block;
import net.minecraft.client.renderer.RenderBlocks;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.util.IIcon;
import net.minecraft.world.IBlockAccess;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
import com.gtnewhorizons.angelica.rendering.celeritas.BiomeVertexBlender;
import com.llamalad7.mixinextras.sugar.Share;
import com.llamalad7.mixinextras.sugar.ref.LocalFloatRef;
import com.llamalad7.mixinextras.sugar.ref.LocalIntRef;
import com.prupe.mcpatcher.cc.ColorizeBlock;
// Only loaded when both cc and ctm are enabled
@Mixin(RenderBlocks.class)
public abstract class MixinRenderBlocks {
@Shadow
public IBlockAccess blockAccess;
@Shadow
public boolean enableAO;
@Shadow
public abstract IIcon getBlockIcon(Block block, IBlockAccess access, int x, int y, int z, int side);
@Shadow
public abstract IIcon getBlockIconFromSideAndMetadata(Block block, int side, int meta);
// Redirect calls to this.getBlockIcon when possible
@Redirect(
method = "renderBlockLiquid(Lnet/minecraft/block/Block;III)Z",
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/client/renderer/RenderBlocks;getBlockIconFromSideAndMetadata(Lnet/minecraft/block/Block;II)Lnet/minecraft/util/IIcon;",
ordinal = 0))
private IIcon mcpatcherforge$obtainFloatsAndRedirectToGetBlockIcon(RenderBlocks instance, Block block, int side,
int meta, Block specializedBlock, int x, int y, int z, @Share("red") LocalFloatRef red,
@Share("green") LocalFloatRef green, @Share("blue") LocalFloatRef blue) {
int l = BiomeVertexBlender.isRendering() ? 0xFFFFFF : block.colorMultiplier(this.blockAccess, x, y, z);
red.set((float) (l >> 16 & 255) / 255.0F);
blue.set((float) (l >> 8 & 255) / 255.0F);
green.set((float) (l & 255) / 255.0F);
return (this.blockAccess == null) ? this.getBlockIconFromSideAndMetadata(block, side, meta)
: this.getBlockIcon(block, this.blockAccess, x, y, z, side);
}
// Capture needed value
@Redirect(
method = "renderBlockLiquid(Lnet/minecraft/block/Block;III)Z",
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/client/renderer/RenderBlocks;getBlockIconFromSideAndMetadata(Lnet/minecraft/block/Block;II)Lnet/minecraft/util/IIcon;",
ordinal = 2))
private IIcon mcpatcherforge$saveSideAndRedirectToGetBlockIcon(RenderBlocks instance, Block block, int side,
int meta, Block specializedBlock, int x, int y, int z, @Share("requiredSide") LocalIntRef requiredSide) {
requiredSide.set(side);
return (this.blockAccess == null) ? this.getBlockIconFromSideAndMetadata(block, side, meta)
: this.getBlockIcon(block, this.blockAccess, x, y, z, side);
}
@Redirect(
method = "renderBlockLiquid(Lnet/minecraft/block/Block;III)Z",
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/client/renderer/Tessellator;setColorOpaque_F(FFF)V",
ordinal = 2))
private void mcpatcherforge$redirectColor10(Tessellator tessellator, float red, float green, float blue,
Block block, int x, int y, int z, @Share("requiredSide") LocalIntRef requiredSide) {
if (!(ColorizeBlock.isSmooth = ColorizeBlock.setupBlockSmoothing(
(RenderBlocks) (Object) this,
block,
this.blockAccess,
x,
y,
z,
requiredSide.get() + 6))) {
tessellator.setColorOpaque_F(red, green, blue);
}
}
@Redirect(
method = "renderBlockLiquid(Lnet/minecraft/block/Block;III)Z",
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/client/renderer/Tessellator;setColorOpaque_F(FFF)V",
ordinal = 1))
private void mcpatcherforge$redirectColor9(Tessellator tessellator, float red, float green, float blue, Block block,
int x, int y, int z, @Share("red") LocalFloatRef redLocal, @Share("green") LocalFloatRef greenLocal,
@Share("blue") LocalFloatRef blueLocal) {
if (!(ColorizeBlock.isSmooth = ColorizeBlock
.setupBlockSmoothing((RenderBlocks) (Object) this, block, this.blockAccess, x, y, z, 6))) {
tessellator.setColorOpaque_F(red * redLocal.get(), green * blueLocal.get(), blue * blueLocal.get());
}
if (ColorizeBlock.isSmooth) {
this.enableAO = true;
}
}
}
@@ -1,48 +0,0 @@
package com.gtnewhorizons.angelica.mixins.early.mcpatcherforge.ctm_cc;
import net.minecraft.block.Block;
import net.minecraft.client.renderer.RenderBlocks;
import net.minecraft.util.IIcon;
import net.minecraft.world.IBlockAccess;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
@Mixin(RenderBlocks.class)
public abstract class MixinRenderBlocksNoCC {
@Shadow
public IBlockAccess blockAccess;
@Shadow
public abstract IIcon getBlockIcon(Block block, IBlockAccess access, int x, int y, int z, int side);
@Shadow
public abstract IIcon getBlockIconFromSideAndMetadata(Block block, int side, int meta);
@Redirect(
method = "renderBlockLiquid(Lnet/minecraft/block/Block;III)Z",
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/client/renderer/RenderBlocks;getBlockIconFromSideAndMetadata(Lnet/minecraft/block/Block;II)Lnet/minecraft/util/IIcon;",
ordinal = 0))
private IIcon mcpatcherforge$redirectToGetBlockIcon(RenderBlocks instance, Block block, int side, int meta,
Block specializedBlock, int x, int y, int z) {
return (this.blockAccess == null) ? this.getBlockIconFromSideAndMetadata(block, side, meta)
: this.getBlockIcon(block, this.blockAccess, x, y, z, side);
}
@Redirect(
method = "renderBlockLiquid(Lnet/minecraft/block/Block;III)Z",
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/client/renderer/RenderBlocks;getBlockIconFromSideAndMetadata(Lnet/minecraft/block/Block;II)Lnet/minecraft/util/IIcon;",
ordinal = 2))
private IIcon mcpatcherforge$saveSideAndRedirectToGetBlockIcon(RenderBlocks instance, Block block, int side,
int meta, Block specializedBlock, int x, int y, int z) {
return (this.blockAccess == null) ? this.getBlockIconFromSideAndMetadata(block, side, meta)
: this.getBlockIcon(block, this.blockAccess, x, y, z, side);
}
}
@@ -1,100 +0,0 @@
package com.gtnewhorizons.angelica.mixins.early.mcpatcherforge.ctm_cc;
import net.minecraft.block.Block;
import net.minecraft.client.renderer.RenderBlocks;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.util.IIcon;
import net.minecraft.world.IBlockAccess;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
import com.gtnewhorizons.angelica.rendering.celeritas.BiomeVertexBlender;
import com.llamalad7.mixinextras.sugar.Share;
import com.llamalad7.mixinextras.sugar.ref.LocalFloatRef;
import com.llamalad7.mixinextras.sugar.ref.LocalIntRef;
import com.prupe.mcpatcher.cc.ColorizeBlock;
@Mixin(RenderBlocks.class)
public abstract class MixinRenderBlocksNoCTM {
@Shadow
public IBlockAccess blockAccess;
@Shadow
public boolean enableAO;
@Shadow
public abstract IIcon getBlockIconFromSideAndMetadata(Block block, int side, int meta);
// Redirect calls to this.getBlockIcon when possible
@Redirect(
method = "renderBlockLiquid(Lnet/minecraft/block/Block;III)Z",
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/client/renderer/RenderBlocks;getBlockIconFromSideAndMetadata(Lnet/minecraft/block/Block;II)Lnet/minecraft/util/IIcon;",
ordinal = 0))
private IIcon mcpatcherforge$obtainFloatsAndRedirectToGetBlockIcon(RenderBlocks instance, Block block, int side,
int meta, Block specializedBlock, int x, int y, int z, @Share("red") LocalFloatRef red,
@Share("green") LocalFloatRef green, @Share("blue") LocalFloatRef blue) {
int l = BiomeVertexBlender.isRendering() ? 0xFFFFFF : block.colorMultiplier(this.blockAccess, x, y, z);
red.set((float) (l >> 16 & 255) / 255.0F);
blue.set((float) (l >> 8 & 255) / 255.0F);
green.set((float) (l & 255) / 255.0F);
return this.getBlockIconFromSideAndMetadata(block, side, meta);
}
// Capture needed value
@Redirect(
method = "renderBlockLiquid(Lnet/minecraft/block/Block;III)Z",
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/client/renderer/RenderBlocks;getBlockIconFromSideAndMetadata(Lnet/minecraft/block/Block;II)Lnet/minecraft/util/IIcon;",
ordinal = 2))
private IIcon mcpatcherforge$saveSideAndRedirectToGetBlockIcon(RenderBlocks instance, Block block, int side,
int meta, Block specializedBlock, int x, int y, int z, @Share("requiredSide") LocalIntRef requiredSide) {
requiredSide.set(side);
return this.getBlockIconFromSideAndMetadata(block, side, meta);
}
@Redirect(
method = "renderBlockLiquid(Lnet/minecraft/block/Block;III)Z",
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/client/renderer/Tessellator;setColorOpaque_F(FFF)V",
ordinal = 2))
private void mcpatcherforge$redirectColor10(Tessellator tessellator, float red, float green, float blue,
Block block, int x, int y, int z, @Share("requiredSide") LocalIntRef requiredSide) {
if (!(ColorizeBlock.isSmooth = ColorizeBlock.setupBlockSmoothing(
(RenderBlocks) (Object) this,
block,
this.blockAccess,
x,
y,
z,
requiredSide.get() + 6))) {
tessellator.setColorOpaque_F(red, green, blue);
}
}
@Redirect(
method = "renderBlockLiquid(Lnet/minecraft/block/Block;III)Z",
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/client/renderer/Tessellator;setColorOpaque_F(FFF)V",
ordinal = 1))
private void mcpatcherforge$redirectColor9(Tessellator tessellator, float red, float green, float blue, Block block,
int x, int y, int z, @Share("red") LocalFloatRef redLocal, @Share("green") LocalFloatRef greenLocal,
@Share("blue") LocalFloatRef blueLocal) {
if (!(ColorizeBlock.isSmooth = ColorizeBlock
.setupBlockSmoothing((RenderBlocks) (Object) this, block, this.blockAccess, x, y, z, 6))) {
tessellator.setColorOpaque_F(red * redLocal.get(), green * blueLocal.get(), blue * blueLocal.get());
}
if (ColorizeBlock.isSmooth) {
this.enableAO = true;
}
}
}
@@ -0,0 +1,45 @@
package net.coderbot.iris.gl.state;
import org.junit.jupiter.api.Test;
import java.util.ArrayList;
import java.util.List;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
class MultiListenerNotifierTest {
@Test
void dedupesAndRunsInRegistrationOrder() {
final List<String> recorded = new ArrayList<>();
final Runnable a = () -> recorded.add("a");
final Runnable b = () -> recorded.add("b");
final MultiListenerNotifier n = new MultiListenerNotifier();
n.setListener(a);
n.setListener(b);
n.setListener(a);
n.run();
assertEquals(List.of("a", "b"), recorded);
}
@Test
void clearDropsAllListeners() {
final List<String> recorded = new ArrayList<>();
final Runnable r1 = () -> recorded.add("1");
final Runnable r2 = () -> recorded.add("2");
final Runnable r3 = () -> recorded.add("3");
final MultiListenerNotifier n = new MultiListenerNotifier();
n.setListener(r1);
n.setListener(r2);
n.setListener(r3);
n.setListener(null);
n.run();
assertTrue(recorded.isEmpty());
n.setListener(r1);
n.setListener(r2);
n.setListener(r3);
n.run();
assertEquals(List.of("1", "2", "3"), recorded);
}
}