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;
|
||||
|
||||
import com.replaymod.render.hooks.MinecraftClientExt;
|
||||
import com.replaymod.render.mixin.MainWindowAccessor;
|
||||
import de.johni0702.minecraft.gui.function.Closeable;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
@@ -16,6 +17,7 @@ public class VirtualWindow implements Closeable {
|
||||
private final MainWindowAccessor acc;
|
||||
|
||||
private final Framebuffer guiFramebuffer;
|
||||
private boolean isBound;
|
||||
private int framebufferWidth, framebufferHeight;
|
||||
|
||||
private int gameWidth, gameHeight;
|
||||
@@ -26,7 +28,8 @@ public class VirtualWindow implements Closeable {
|
||||
this.window = mc.getWindow();
|
||||
this.acc = (MainWindowAccessor) (Object) this.window;
|
||||
|
||||
updateFramebufferSize();
|
||||
framebufferWidth = acc.getFramebufferWidth();
|
||||
framebufferHeight = acc.getFramebufferHeight();
|
||||
|
||||
//#if MC>=11700
|
||||
//$$ guiFramebuffer = new WindowFramebuffer(framebufferWidth, framebufferHeight);
|
||||
@@ -37,11 +40,15 @@ public class VirtualWindow implements Closeable {
|
||||
//#endif
|
||||
);
|
||||
//#endif
|
||||
|
||||
MinecraftClientExt.get(mc).setWindowDelegate(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
guiFramebuffer.delete();
|
||||
|
||||
MinecraftClientExt.get(mc).setWindowDelegate(null);
|
||||
}
|
||||
|
||||
public void bind() {
|
||||
@@ -49,11 +56,13 @@ public class VirtualWindow implements Closeable {
|
||||
gameHeight = acc.getFramebufferHeight();
|
||||
acc.setFramebufferWidth(framebufferWidth);
|
||||
acc.setFramebufferHeight(framebufferHeight);
|
||||
isBound = true;
|
||||
}
|
||||
|
||||
public void unbind() {
|
||||
acc.setFramebufferWidth(gameWidth);
|
||||
acc.setFramebufferHeight(gameHeight);
|
||||
isBound = false;
|
||||
}
|
||||
|
||||
public void beginWrite() {
|
||||
@@ -82,36 +91,45 @@ public class VirtualWindow implements Closeable {
|
||||
//#endif
|
||||
}
|
||||
|
||||
public void updateSize() {
|
||||
// Resize the GUI framebuffer if the display size changed
|
||||
if (framebufferSizeChanged()) {
|
||||
updateFramebufferSize();
|
||||
//#if MC>=11400
|
||||
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) {
|
||||
/**
|
||||
* Updates the size of the window's framebuffer. Must only be called while this window is bound.
|
||||
*/
|
||||
public void onResolutionChanged(int newWidth, int newHeight) {
|
||||
if (newWidth == 0 || newHeight == 0) {
|
||||
// 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.
|
||||
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() {
|
||||
framebufferWidth = mc.getWindow().getFramebufferWidth();
|
||||
framebufferHeight = mc.getWindow().getFramebufferHeight();
|
||||
private void applyScaleFactor() {
|
||||
//#if MC>=11400
|
||||
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() {
|
||||
@@ -121,4 +139,8 @@ public class VirtualWindow implements Closeable {
|
||||
public int getFramebufferHeight() {
|
||||
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();
|
||||
@Accessor
|
||||
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;
|
||||
}
|
||||
|
||||
guiWindow.updateSize();
|
||||
|
||||
pushMatrix();
|
||||
GlStateManager.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT
|
||||
//#if MC>=11400
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
"Mixin_StabilizeCamera",
|
||||
"Mixin_Stereoscopic_Camera",
|
||||
"Mixin_Stereoscopic_HandRenderPass",
|
||||
"Mixin_SuppressFramebufferResizeDuringRender",
|
||||
//#if MC>=11600
|
||||
"Mixin_AddIrisOdsShaderUniforms",
|
||||
"Mixin_LoadIrisOdsShaderPack",
|
||||
|
||||
Reference in New Issue
Block a user