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 org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
import org.spongepowered.asm.mixin.gen.Invoker;
@Mixin(Window.class)
public interface MainWindowAccessor {
@@ -14,4 +15,12 @@ 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();
}

View File

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

View File

@@ -34,6 +34,11 @@ public class Window implements MainWindowAccessor {
mc.displayHeight = value;
}
@Override
public void invokeUpdateFramebufferSize() {
// no-op, pre-LWJGL3 MC doesn't differentiate between window and framebuffer size
}
public long getHandle() {
return 0;
}

View File

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