package com.replaymod.render.capturer; import com.replaymod.core.versions.MCVer; import com.replaymod.render.frame.OpenGlFrame; import com.replaymod.render.rendering.Frame; import com.replaymod.render.rendering.FrameCapturer; import com.replaymod.render.utils.ByteBufferPool; import de.johni0702.minecraft.gui.utils.lwjgl.Dimension; import de.johni0702.minecraft.gui.utils.lwjgl.ReadableDimension; import de.johni0702.minecraft.gui.utils.lwjgl.WritableDimension; import net.minecraft.client.Minecraft; import net.minecraft.client.shader.Framebuffer; import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL12; import java.io.IOException; import java.nio.ByteBuffer; //#if MC>=11300 import com.replaymod.render.mixin.MainWindowAccessor; //#endif //#if MC>=10800 import static net.minecraft.client.renderer.GlStateManager.*; //#else //$$ import static com.replaymod.core.versions.MCVer.GlStateManager.*; //#endif import static org.lwjgl.opengl.GL11.GL_COLOR_BUFFER_BIT; import static org.lwjgl.opengl.GL11.GL_DEPTH_BUFFER_BIT; public abstract class OpenGlFrameCapturer implements FrameCapturer { protected final WorldRenderer worldRenderer; protected final RenderInfo renderInfo; protected int framesDone; private Framebuffer frameBuffer; private final Minecraft mc = MCVer.getMinecraft(); public OpenGlFrameCapturer(WorldRenderer worldRenderer, RenderInfo renderInfo) { this.worldRenderer = worldRenderer; this.renderInfo = renderInfo; } protected final ReadableDimension frameSize = new ReadableDimension() { @Override public int getWidth() { return getFrameWidth(); } @Override public int getHeight() { return getFrameHeight(); } @Override public void getSize(WritableDimension dest) { dest.setSize(getWidth(), getHeight()); } }; protected int getFrameWidth() { return renderInfo.getFrameSize().getWidth(); } protected int getFrameHeight() { return renderInfo.getFrameSize().getHeight(); } protected Framebuffer frameBuffer() { if (frameBuffer == null) { frameBuffer = mc.getFramebuffer(); } return frameBuffer; } @Override public boolean isDone() { return framesDone >= renderInfo.getTotalFrames(); } protected OpenGlFrame renderFrame(int frameId, float partialTicks) { return renderFrame(frameId, partialTicks, null); } protected OpenGlFrame renderFrame(int frameId, float partialTicks, D captureData) { resize(getFrameWidth(), getFrameHeight()); pushMatrix(); frameBuffer().bindFramebuffer(true); clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT //#if MC>=11400 //$$ , false //#endif ); enableTexture2D(); worldRenderer.renderWorld(partialTicks, captureData); frameBuffer().unbindFramebuffer(); popMatrix(); return captureFrame(frameId, captureData); } protected OpenGlFrame captureFrame(int frameId, D captureData) { ByteBuffer buffer = ByteBufferPool.allocate(getFrameWidth() * getFrameHeight() * 4); frameBuffer().bindFramebuffer(true); GL11.glReadPixels(0, 0, getFrameWidth(), getFrameHeight(), GL12.GL_BGRA, GL11.GL_UNSIGNED_BYTE, buffer); frameBuffer().unbindFramebuffer(); buffer.rewind(); return new OpenGlFrame(frameId, new Dimension(getFrameWidth(), getFrameHeight()), buffer); } protected void resize(int width, int height) { //#if MC>=11300 Framebuffer fb = mc.getFramebuffer(); if (fb.framebufferWidth != width || fb.framebufferHeight != height) { fb.createFramebuffer(width, height //#if MC>=11400 //$$ , false //#endif ); } //noinspection ConstantConditions MainWindowAccessor mainWindow = (MainWindowAccessor) (Object) mc.mainWindow; mainWindow.setFramebufferWidth(width); mainWindow.setFramebufferHeight(height); //#else //$$ if (width != mc.displayWidth || height != mc.displayHeight) { //$$ mc.resize(width, height); //$$ } //#endif } @Override public void close() throws IOException { worldRenderer.close(); } }