Completely bypass Minecraft when window is resized during rendering
Should fix issues where resizing affects the render result.
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
package com.replaymod.render.gui.progress;
|
package com.replaymod.render.gui.progress;
|
||||||
|
|
||||||
|
import com.replaymod.render.hooks.MinecraftClientExt;
|
||||||
import com.replaymod.render.mixin.MainWindowAccessor;
|
import com.replaymod.render.mixin.MainWindowAccessor;
|
||||||
import de.johni0702.minecraft.gui.function.Closeable;
|
import de.johni0702.minecraft.gui.function.Closeable;
|
||||||
import net.minecraft.client.MinecraftClient;
|
import net.minecraft.client.MinecraftClient;
|
||||||
@@ -16,6 +17,7 @@ public class VirtualWindow implements Closeable {
|
|||||||
private final MainWindowAccessor acc;
|
private final MainWindowAccessor acc;
|
||||||
|
|
||||||
private final Framebuffer guiFramebuffer;
|
private final Framebuffer guiFramebuffer;
|
||||||
|
private boolean isBound;
|
||||||
private int framebufferWidth, framebufferHeight;
|
private int framebufferWidth, framebufferHeight;
|
||||||
|
|
||||||
private int gameWidth, gameHeight;
|
private int gameWidth, gameHeight;
|
||||||
@@ -26,7 +28,8 @@ public class VirtualWindow implements Closeable {
|
|||||||
this.window = mc.getWindow();
|
this.window = mc.getWindow();
|
||||||
this.acc = (MainWindowAccessor) (Object) this.window;
|
this.acc = (MainWindowAccessor) (Object) this.window;
|
||||||
|
|
||||||
updateFramebufferSize();
|
framebufferWidth = acc.getFramebufferWidth();
|
||||||
|
framebufferHeight = acc.getFramebufferHeight();
|
||||||
|
|
||||||
//#if MC>=11700
|
//#if MC>=11700
|
||||||
//$$ guiFramebuffer = new WindowFramebuffer(framebufferWidth, framebufferHeight);
|
//$$ guiFramebuffer = new WindowFramebuffer(framebufferWidth, framebufferHeight);
|
||||||
@@ -37,11 +40,15 @@ public class VirtualWindow implements Closeable {
|
|||||||
//#endif
|
//#endif
|
||||||
);
|
);
|
||||||
//#endif
|
//#endif
|
||||||
|
|
||||||
|
MinecraftClientExt.get(mc).setWindowDelegate(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void close() {
|
public void close() {
|
||||||
guiFramebuffer.delete();
|
guiFramebuffer.delete();
|
||||||
|
|
||||||
|
MinecraftClientExt.get(mc).setWindowDelegate(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void bind() {
|
public void bind() {
|
||||||
@@ -49,11 +56,13 @@ public class VirtualWindow implements Closeable {
|
|||||||
gameHeight = acc.getFramebufferHeight();
|
gameHeight = acc.getFramebufferHeight();
|
||||||
acc.setFramebufferWidth(framebufferWidth);
|
acc.setFramebufferWidth(framebufferWidth);
|
||||||
acc.setFramebufferHeight(framebufferHeight);
|
acc.setFramebufferHeight(framebufferHeight);
|
||||||
|
isBound = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void unbind() {
|
public void unbind() {
|
||||||
acc.setFramebufferWidth(gameWidth);
|
acc.setFramebufferWidth(gameWidth);
|
||||||
acc.setFramebufferHeight(gameHeight);
|
acc.setFramebufferHeight(gameHeight);
|
||||||
|
isBound = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void beginWrite() {
|
public void beginWrite() {
|
||||||
@@ -82,36 +91,45 @@ public class VirtualWindow implements Closeable {
|
|||||||
//#endif
|
//#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateSize() {
|
/**
|
||||||
// Resize the GUI framebuffer if the display size changed
|
* Updates the size of the window's framebuffer. Must only be called while this window is bound.
|
||||||
if (framebufferSizeChanged()) {
|
*/
|
||||||
updateFramebufferSize();
|
public void onResolutionChanged(int newWidth, int newHeight) {
|
||||||
//#if MC>=11400
|
if (newWidth == 0 || newHeight == 0) {
|
||||||
guiFramebuffer.resize(framebufferWidth, framebufferHeight
|
|
||||||
//#if MC>=11400
|
|
||||||
, false
|
|
||||||
//#endif
|
|
||||||
);
|
|
||||||
//#else
|
|
||||||
//$$ guiFramebuffer.createBindFramebuffer(framebufferWidth, framebufferHeight);
|
|
||||||
//#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean framebufferSizeChanged() {
|
|
||||||
int realWidth = mc.getWindow().getFramebufferWidth();
|
|
||||||
int realHeight = mc.getWindow().getFramebufferHeight();
|
|
||||||
if (realWidth == 0 || realHeight == 0) {
|
|
||||||
// These can be zero on Windows if minimized.
|
// These can be zero on Windows if minimized.
|
||||||
// Creating zero-sized framebuffers however will throw an error, so we never want to switch to zero values.
|
// Creating zero-sized framebuffers however will throw an error, so we never want to switch to zero values.
|
||||||
return false;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (framebufferWidth == newWidth && framebufferHeight == newHeight) {
|
||||||
|
return; // size is unchanged, nothing to do
|
||||||
|
}
|
||||||
|
|
||||||
|
framebufferWidth = newWidth;
|
||||||
|
framebufferHeight = newHeight;
|
||||||
|
|
||||||
|
//#if MC>=11400
|
||||||
|
guiFramebuffer.resize(newWidth, newHeight
|
||||||
|
//#if MC>=11400
|
||||||
|
, false
|
||||||
|
//#endif
|
||||||
|
);
|
||||||
|
//#else
|
||||||
|
//$$ guiFramebuffer.createBindFramebuffer(newWidth, newHeight);
|
||||||
|
//#endif
|
||||||
|
|
||||||
|
applyScaleFactor();
|
||||||
|
if (mc.currentScreen != null) {
|
||||||
|
mc.currentScreen.resize(mc, window.getScaledWidth(), window.getScaledHeight());
|
||||||
}
|
}
|
||||||
return framebufferWidth != realWidth || framebufferHeight != realHeight;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateFramebufferSize() {
|
private void applyScaleFactor() {
|
||||||
framebufferWidth = mc.getWindow().getFramebufferWidth();
|
//#if MC>=11400
|
||||||
framebufferHeight = mc.getWindow().getFramebufferHeight();
|
window.setScaleFactor(window.calculateScaleFactor(mc.options.guiScale, mc.forcesUnicodeFont()));
|
||||||
|
//#else
|
||||||
|
//$$ // Nothing to do, ScaledResolution re-computes the scale factor every time it is created
|
||||||
|
//#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getFramebufferWidth() {
|
public int getFramebufferWidth() {
|
||||||
@@ -121,4 +139,8 @@ public class VirtualWindow implements Closeable {
|
|||||||
public int getFramebufferHeight() {
|
public int getFramebufferHeight() {
|
||||||
return framebufferHeight;
|
return framebufferHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isBound() {
|
||||||
|
return isBound;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,12 @@
|
|||||||
|
package com.replaymod.render.hooks;
|
||||||
|
|
||||||
|
import com.replaymod.render.gui.progress.VirtualWindow;
|
||||||
|
import net.minecraft.client.MinecraftClient;
|
||||||
|
|
||||||
|
public interface MinecraftClientExt {
|
||||||
|
void setWindowDelegate(VirtualWindow window);
|
||||||
|
|
||||||
|
static MinecraftClientExt get(MinecraftClient mc) {
|
||||||
|
return (MinecraftClientExt) mc;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -15,12 +15,4 @@ public interface MainWindowAccessor {
|
|||||||
int getFramebufferHeight();
|
int getFramebufferHeight();
|
||||||
@Accessor
|
@Accessor
|
||||||
void setFramebufferHeight(int value);
|
void setFramebufferHeight(int value);
|
||||||
// FIXME preprocessor should be able to infer this mapping
|
|
||||||
// FIXME preprocessor should be able to remap this one when the mapping is given manually
|
|
||||||
//#if MC>=11500
|
|
||||||
@Invoker
|
|
||||||
//#else
|
|
||||||
//$$ @Invoker("method_4483")
|
|
||||||
//#endif
|
|
||||||
void invokeUpdateFramebufferSize();
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,39 @@
|
|||||||
|
package com.replaymod.render.mixin;
|
||||||
|
|
||||||
|
import com.replaymod.render.gui.progress.VirtualWindow;
|
||||||
|
import com.replaymod.render.hooks.MinecraftClientExt;
|
||||||
|
import net.minecraft.client.MinecraftClient;
|
||||||
|
import net.minecraft.client.util.Window;
|
||||||
|
import org.spongepowered.asm.mixin.Final;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
|
import org.spongepowered.asm.mixin.Unique;
|
||||||
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
|
||||||
|
@Mixin(MinecraftClient.class)
|
||||||
|
public class Mixin_SuppressFramebufferResizeDuringRender implements MinecraftClientExt {
|
||||||
|
|
||||||
|
@Unique
|
||||||
|
private VirtualWindow windowDelegate;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setWindowDelegate(VirtualWindow window) {
|
||||||
|
this.windowDelegate = window;
|
||||||
|
}
|
||||||
|
|
||||||
|
//#if MC>=11400
|
||||||
|
@Inject(method = "onResolutionChanged", at = @At("HEAD"), cancellable = true)
|
||||||
|
//#else
|
||||||
|
//$$ @Inject(method = "resize", at = @At("HEAD"), cancellable = true)
|
||||||
|
//#endif
|
||||||
|
private void suppressResizeDuringRender(CallbackInfo ci) {
|
||||||
|
VirtualWindow delegate = this.windowDelegate;
|
||||||
|
if (delegate != null && delegate.isBound()) {
|
||||||
|
Window window = ((MinecraftClient) (Object) this).getWindow();
|
||||||
|
delegate.onResolutionChanged(window.getFramebufferWidth(), window.getFramebufferHeight());
|
||||||
|
ci.cancel();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -462,8 +462,6 @@ public class VideoRenderer implements RenderInfo {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
guiWindow.updateSize();
|
|
||||||
|
|
||||||
pushMatrix();
|
pushMatrix();
|
||||||
GlStateManager.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT
|
GlStateManager.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT
|
||||||
//#if MC>=11400
|
//#if MC>=11400
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
"Mixin_StabilizeCamera",
|
"Mixin_StabilizeCamera",
|
||||||
"Mixin_Stereoscopic_Camera",
|
"Mixin_Stereoscopic_Camera",
|
||||||
"Mixin_Stereoscopic_HandRenderPass",
|
"Mixin_Stereoscopic_HandRenderPass",
|
||||||
|
"Mixin_SuppressFramebufferResizeDuringRender",
|
||||||
//#if MC>=11600
|
//#if MC>=11600
|
||||||
"Mixin_AddIrisOdsShaderUniforms",
|
"Mixin_AddIrisOdsShaderUniforms",
|
||||||
"Mixin_LoadIrisOdsShaderPack",
|
"Mixin_LoadIrisOdsShaderPack",
|
||||||
|
|||||||
@@ -33,11 +33,6 @@ public class Window implements MainWindowAccessor {
|
|||||||
mc.displayHeight = value;
|
mc.displayHeight = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void invokeUpdateFramebufferSize() {
|
|
||||||
// no-op, pre-LWJGL3 MC doesn't differentiate between window and framebuffer size
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getHandle() {
|
public long getHandle() {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,4 @@ public interface MainWindowAccessor {
|
|||||||
int getFramebufferHeight();
|
int getFramebufferHeight();
|
||||||
@Accessor("displayHeight")
|
@Accessor("displayHeight")
|
||||||
void setFramebufferHeight(int value);
|
void setFramebufferHeight(int value);
|
||||||
@Invoker
|
|
||||||
void invokeUpdateFramebufferSize();
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -181,6 +181,7 @@ net.minecraft.client.gui.screen.Screen hasShiftDown() isShiftKeyDown()
|
|||||||
net.minecraft.client.gui.screen.Screen init() setWorldAndResolution()
|
net.minecraft.client.gui.screen.Screen init() setWorldAndResolution()
|
||||||
net.minecraft.client.gui.screen.Screen minecraft mc
|
net.minecraft.client.gui.screen.Screen minecraft mc
|
||||||
net.minecraft.client.gui.screen.Screen net.minecraft.client.gui.GuiScreen
|
net.minecraft.client.gui.screen.Screen net.minecraft.client.gui.GuiScreen
|
||||||
|
net.minecraft.client.gui.screen.Screen resize() onResize()
|
||||||
net.minecraft.client.gui.screen.Screen passEvents allowUserInput
|
net.minecraft.client.gui.screen.Screen passEvents allowUserInput
|
||||||
net.minecraft.client.gui.screen.Screen removed() onGuiClosed()
|
net.minecraft.client.gui.screen.Screen removed() onGuiClosed()
|
||||||
net.minecraft.client.gui.screen.Screen renderBackground() drawDefaultBackground()
|
net.minecraft.client.gui.screen.Screen renderBackground() drawDefaultBackground()
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
net.minecraft.client.gui.GuiScreen onResize() func_175273_b()
|
||||||
net.minecraft.entity.player.EntityPlayer isWearing() func_175148_a()
|
net.minecraft.entity.player.EntityPlayer isWearing() func_175148_a()
|
||||||
net.minecraft.client.renderer.WorldRenderer begin() startDrawing()
|
net.minecraft.client.renderer.WorldRenderer begin() startDrawing()
|
||||||
net.minecraft.network.play.server.S38PacketPlayerListItem getAction() func_179768_b()
|
net.minecraft.network.play.server.S38PacketPlayerListItem getAction() func_179768_b()
|
||||||
|
|||||||
Reference in New Issue
Block a user