Fix Render GUI on Retina Screens (fixes #338)

window.getFramebufferWidth/Height() should be used instead of window.getWidth/Height()

Co-authored-by: Jonas Herzig <me@johni0702.de>
This commit is contained in:
Andrew S
2021-12-25 20:01:48 -05:00
committed by Jonas Herzig
parent e378ae8f93
commit 7e9a1e7c13
4 changed files with 50 additions and 14 deletions

View File

@@ -3,6 +3,7 @@ package com.replaymod.render.mixin;
import net.minecraft.client.util.Window; import net.minecraft.client.util.Window;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor; import org.spongepowered.asm.mixin.gen.Accessor;
import org.spongepowered.asm.mixin.gen.Invoker;
@Mixin(Window.class) @Mixin(Window.class)
public interface MainWindowAccessor { public interface MainWindowAccessor {
@@ -14,4 +15,12 @@ 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();
} }

View File

@@ -120,6 +120,7 @@ public class VideoRenderer implements RenderInfo {
private Framebuffer guiFramebuffer; private Framebuffer guiFramebuffer;
private int displayWidth, displayHeight; private int displayWidth, displayHeight;
private int framebufferWidth, framebufferHeight;
public VideoRenderer(RenderSettings settings, ReplayHandler replayHandler, Timeline timeline) throws IOException { public VideoRenderer(RenderSettings settings, ReplayHandler replayHandler, Timeline timeline) throws IOException {
this.settings = settings; this.settings = settings;
@@ -245,10 +246,10 @@ public class VideoRenderer implements RenderInfo {
public float updateForNextFrame() { public float updateForNextFrame() {
// because the jGui lib uses Minecraft's displayWidth and displayHeight values, update these temporarily // because the jGui lib uses Minecraft's displayWidth and displayHeight values, update these temporarily
MainWindowAccessor acc = (MainWindowAccessor) (Object) mc.getWindow(); MainWindowAccessor acc = (MainWindowAccessor) (Object) mc.getWindow();
int displayWidthBefore = acc.getFramebufferWidth(); int framebufferWidthBefore = acc.getFramebufferWidth();
int displayHeightBefore = acc.getFramebufferHeight(); int framebufferHeightBefore = acc.getFramebufferHeight();
acc.setFramebufferWidth(displayWidth); acc.setFramebufferWidth(framebufferWidth);
acc.setFramebufferHeight(displayHeight); acc.setFramebufferHeight(framebufferHeight);
if (!settings.isHighPerformance() || framesDone % fps == 0) { if (!settings.isHighPerformance() || framesDone % fps == 0) {
while (drawGui() && paused) { while (drawGui() && paused) {
@@ -289,8 +290,8 @@ public class VideoRenderer implements RenderInfo {
} }
// change Minecraft's display size back // change Minecraft's display size back
acc.setFramebufferWidth(displayWidthBefore); acc.setFramebufferWidth(framebufferWidthBefore);
acc.setFramebufferHeight(displayHeightBefore); acc.setFramebufferHeight(framebufferHeightBefore);
if (cameraPathExporter != null) { if (cameraPathExporter != null) {
cameraPathExporter.recordFrame(timer.tickDelta); cameraPathExporter.recordFrame(timer.tickDelta);
@@ -362,6 +363,7 @@ public class VideoRenderer implements RenderInfo {
} }
updateDisplaySize(); updateDisplaySize();
updateFramebufferSize();
gui.toMinecraft().init(mc, mc.getWindow().getScaledWidth(), mc.getWindow().getScaledHeight()); gui.toMinecraft().init(mc, mc.getWindow().getScaledWidth(), mc.getWindow().getScaledHeight());
@@ -369,9 +371,9 @@ public class VideoRenderer implements RenderInfo {
// Set up our own framebuffer to render the GUI to // Set up our own framebuffer to render the GUI to
//#if MC>=11700 //#if MC>=11700
//$$ guiFramebuffer = new WindowFramebuffer(displayWidth, displayHeight); //$$ guiFramebuffer = new WindowFramebuffer(framebufferWidth, framebufferHeight);
//#else //#else
guiFramebuffer = new Framebuffer(displayWidth, displayHeight, true guiFramebuffer = new Framebuffer(framebufferWidth, framebufferHeight, true
//#if MC>=11400 //#if MC>=11400
, false , false
//#endif //#endif
@@ -425,7 +427,7 @@ public class VideoRenderer implements RenderInfo {
} }
// Finally, resize the Minecraft framebuffer to the actual width/height of the window // Finally, resize the Minecraft framebuffer to the actual width/height of the window
resizeMainWindow(mc, displayWidth, displayHeight); resizeMainWindow(mc, framebufferWidth, framebufferHeight);
} }
private void executeTaskQueue() { private void executeTaskQueue() {
@@ -483,17 +485,23 @@ public class VideoRenderer implements RenderInfo {
return false; return false;
} }
// Resize the GUI framebuffer if the display size changed // Check if display size has changes and force recalculate GUI framebuffer size.
if (displaySizeChanged()) { if (displaySizeChanged()) {
updateDisplaySize(); updateDisplaySize();
((MainWindowAccessor) (Object) window).invokeUpdateFramebufferSize();
}
// Resize the GUI framebuffer if the display size changed
if (framebufferSizeChanged()) {
updateFramebufferSize();
//#if MC>=11400 //#if MC>=11400
guiFramebuffer.resize(displayWidth, displayHeight guiFramebuffer.resize(framebufferWidth, framebufferHeight
//#if MC>=11400 //#if MC>=11400
, false , false
//#endif //#endif
); );
//#else //#else
//$$ guiFramebuffer.createBindFramebuffer(mc.displayWidth, mc.displayHeight); //$$ guiFramebuffer.createBindFramebuffer(framebufferWidth, framebufferHeight);
//#endif //#endif
} }
@@ -594,7 +602,7 @@ public class VideoRenderer implements RenderInfo {
guiFramebuffer.endWrite(); guiFramebuffer.endWrite();
popMatrix(); popMatrix();
pushMatrix(); pushMatrix();
guiFramebuffer.draw(displayWidth, displayHeight); guiFramebuffer.draw(framebufferWidth, framebufferHeight);
popMatrix(); popMatrix();
//#if MC>=11500 //#if MC>=11500
@@ -633,12 +641,18 @@ public class VideoRenderer implements RenderInfo {
private boolean displaySizeChanged() { private boolean displaySizeChanged() {
int realWidth = mc.getWindow().getWidth(); int realWidth = mc.getWindow().getWidth();
int realHeight = mc.getWindow().getHeight(); int realHeight = mc.getWindow().getHeight();
return displayWidth != realWidth || displayHeight != realHeight;
}
private boolean framebufferSizeChanged() {
int realWidth = mc.getWindow().getFramebufferWidth();
int realHeight = mc.getWindow().getFramebufferHeight();
if (realWidth == 0 || realHeight == 0) { 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 false;
} }
return displayWidth != realWidth || displayHeight != realHeight; return framebufferWidth != realWidth || framebufferHeight != realHeight;
} }
private void updateDisplaySize() { private void updateDisplaySize() {
@@ -646,6 +660,11 @@ public class VideoRenderer implements RenderInfo {
displayHeight = mc.getWindow().getHeight(); displayHeight = mc.getWindow().getHeight();
} }
private void updateFramebufferSize() {
framebufferWidth = mc.getWindow().getFramebufferWidth();
framebufferHeight = mc.getWindow().getFramebufferHeight();
}
public int getFramesDone() { public int getFramesDone() {
return framesDone; return framesDone;
} }

View File

@@ -34,6 +34,11 @@ 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;
} }

View File

@@ -3,6 +3,7 @@ package com.replaymod.render.mixin;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor; import org.spongepowered.asm.mixin.gen.Accessor;
import org.spongepowered.asm.mixin.gen.Invoker;
@Mixin(Minecraft.class) @Mixin(Minecraft.class)
public interface MainWindowAccessor { public interface MainWindowAccessor {
@@ -14,4 +15,6 @@ public interface MainWindowAccessor {
int getFramebufferHeight(); int getFramebufferHeight();
@Accessor("displayHeight") @Accessor("displayHeight")
void setFramebufferHeight(int value); void setFramebufferHeight(int value);
@Invoker
void invokeUpdateFramebufferSize();
} }