Allow custom resolution for all video rendering modes

Remove tiled rendering
Choose different rendering strategy based on video size and framebuffer support
Make size of video writer queue configurable via system properties
This commit is contained in:
johni0702
2015-06-03 21:19:41 +02:00
parent 6b038adaa1
commit d171ff4346
25 changed files with 855 additions and 452 deletions

View File

@@ -3,6 +3,8 @@ package eu.crushedpixel.replaymod.video.entity;
import eu.crushedpixel.replaymod.renderer.SpectatorRenderer;
import eu.crushedpixel.replaymod.replay.ReplayHandler;
import eu.crushedpixel.replaymod.settings.RenderOptions;
import eu.crushedpixel.replaymod.utils.OpenGLUtils;
import eu.crushedpixel.replaymod.video.entity.strategy.*;
import net.minecraft.client.Minecraft;
import net.minecraft.client.particle.EffectRenderer;
import net.minecraft.client.renderer.*;
@@ -14,53 +16,103 @@ import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.AxisAlignedBB;
import net.minecraft.util.EnumWorldBlockLayer;
import net.minecraft.util.MathHelper;
import net.minecraft.util.ResourceLocation;
import org.lwjgl.util.glu.Project;
import java.awt.image.BufferedImage;
import static net.minecraft.client.renderer.GlStateManager.*;
import static org.lwjgl.opengl.GL11.*;
public abstract class CustomEntityRenderer {
protected final Minecraft mc = Minecraft.getMinecraft();
protected final EntityRenderer proxied = mc.entityRenderer;
public final Minecraft mc = Minecraft.getMinecraft();
public final EntityRenderer proxied = mc.entityRenderer;
protected final SpectatorRenderer spectatorRenderer = new SpectatorRenderer(){
@Override
protected void gluPerspective(float fovY, float aspect, float zNear, float zFar) {
CustomEntityRenderer.this.gluPerspective(fovY, aspect, zNear, zFar);
}
};
protected final FrameRenderingStrategy renderingStrategy;
public GluPerspectiveHook gluPerspectiveHook;
public LoadShaderHook loadShaderHook;
protected int frameCount;
protected final RenderOptions options;
public final int resultWidth;
public final int resultHeight;
public CustomEntityRenderer(RenderOptions options) {
this(options, options.getWidth(), options.getHeight());
}
public CustomEntityRenderer(RenderOptions options, int resultWidth, int resultHeight) {
this.options = options;
}
this.resultWidth = resultWidth;
this.resultHeight = resultHeight;
protected void gluPerspective(float fovY, float aspect, float zNear, float zFar) {
Project.gluPerspective(fovY, aspect, zNear, zFar);
}
public void updateCameraAndRender(float renderPartialTicks) {
if (mc.theWorld != null) {
renderWorld(renderPartialTicks, 0);
if (OpenGlHelper.shadersSupported) {
mc.renderGlobal.renderEntityOutlineFramebuffer();
if (proxied.theShaderGroup != null && proxied.useShader) {
matrixMode(GL_TEXTURE);
pushMatrix();
loadIdentity();
proxied.theShaderGroup.loadShaderGroup(renderPartialTicks);
popMatrix();
}
mc.getFramebuffer().bindFramebuffer(true);
if (OpenGlHelper.isFramebufferEnabled()) {
if (resultWidth > OpenGLUtils.VIEWPORT_MAX_WIDTH || resultHeight > OpenGLUtils.VIEWPORT_MAX_HEIGHT) {
// Video resolution only limited by available RAM and disk size
renderingStrategy = new TiledFrameBufferRenderingStrategy(this);
} else {
// This strategy supports shader
renderingStrategy = new VanillaFrameBufferRenderingStrategy(this);
}
} else {
if (resultWidth > mc.displayHeight || resultHeight > mc.displayHeight) {
// Video resolution only limited by available RAM and disk size
renderingStrategy = new TiledReadPixelsRenderingStrategy(this);
} else {
// Simplest and fastest strategy if frame buffers aren't supported
renderingStrategy = new VanillaReadPixelsRenderingStrategy(this);
}
}
System.out.println("CustomEntityRenderer using " + renderingStrategy);
}
@SuppressWarnings("unused") // Method called by ASM hook
protected void loadShader(ResourceLocation resourceLocation) {
if (loadShaderHook != null) {
loadShaderHook.loadShader(resourceLocation);
} else {
original_loadShader(resourceLocation);
}
}
protected void renderWorld(float partialTicks, long finishTimeNano) {
@SuppressWarnings("unused")
protected final void original_loadShader(ResourceLocation resourceLocation) {
// Method body generated by ASM
}
protected void gluPerspective(float fovY, float aspect, float zNear, float zFar) {
if (gluPerspectiveHook == null) {
Project.gluPerspective(fovY, aspect, zNear, zFar);
} else {
gluPerspectiveHook.gluPerspective(fovY, aspect, zNear, zFar);
}
}
public void renderFrame(float partialTicks, BufferedImage into, int x, int y) {
if (mc.theWorld != null) {
renderingStrategy.renderFrame(partialTicks, into, x, y);
}
}
public void withDisplaySize(int displayWidth, int displayHeight, Runnable runnable) {
final int prevWidth = mc.displayWidth;
final int prevHeight = mc.displayHeight;
mc.displayWidth = displayWidth;
mc.displayHeight = displayHeight;
runnable.run();
mc.displayWidth = prevWidth;
mc.displayHeight = prevHeight;
}
public void renderWorld(float partialTicks, long finishTimeNano) {
proxied.updateLightmap(partialTicks);
enableDepth();
@@ -247,6 +299,11 @@ public abstract class CustomEntityRenderer {
}
}
public void cleanup() {
renderingStrategy.cleanup();
spectatorRenderer.cleanup();
}
public static final class NoCullingCamera implements ICamera {
@Override
@@ -259,4 +316,12 @@ public abstract class CustomEntityRenderer {
}
}
public static interface GluPerspectiveHook {
void gluPerspective(float fovY, float aspect, float zNear, float zFar);
}
public static interface LoadShaderHook {
void loadShader(ResourceLocation resourceLocation);
}
}