166 lines
6.1 KiB
Java
166 lines
6.1 KiB
Java
package com.replaymod.render.capturer;
|
|
|
|
import com.replaymod.render.RenderSettings;
|
|
import com.replaymod.render.frame.CubicOpenGlFrame;
|
|
import com.replaymod.render.frame.ODSOpenGlFrame;
|
|
import com.replaymod.render.frame.OpenGlFrame;
|
|
import com.replaymod.render.rendering.FrameCapturer;
|
|
import com.replaymod.render.shader.Program;
|
|
import net.minecraft.client.Minecraft;
|
|
import net.minecraft.client.renderer.GlStateManager;
|
|
import net.minecraft.crash.CrashReport;
|
|
import net.minecraft.util.ReportedException;
|
|
import net.minecraft.util.ResourceLocation;
|
|
import org.lwjgl.util.ReadableDimension;
|
|
|
|
import java.io.IOException;
|
|
|
|
import static net.minecraft.client.renderer.GlStateManager.*;
|
|
import static org.lwjgl.opengl.GL11.GL_COLOR_BUFFER_BIT;
|
|
import static org.lwjgl.opengl.GL11.GL_DEPTH_BUFFER_BIT;
|
|
|
|
public class ODSFrameCapturer implements FrameCapturer<ODSOpenGlFrame> {
|
|
private static final ResourceLocation vertexResource = new ResourceLocation("replaymod", "shader/ods.vert");
|
|
private static final ResourceLocation fragmentResource = new ResourceLocation("replaymod", "shader/ods.frag");
|
|
|
|
private final CubicPboOpenGlFrameCapturer left, right;
|
|
private final Program shaderProgram;
|
|
private final Program.Uniform directionVariable;
|
|
private final Program.Uniform leftEyeVariable;
|
|
|
|
private final BooleanState[] previousStates = new BooleanState[3];
|
|
private final BooleanState previousFogState;
|
|
|
|
private final Minecraft mc = Minecraft.getMinecraft();
|
|
|
|
public ODSFrameCapturer(WorldRenderer worldRenderer, final RenderInfo renderInfo, int frameSize) {
|
|
RenderInfo fakeInfo = new RenderInfo() {
|
|
private int call;
|
|
private float partialTicks;
|
|
@Override
|
|
public ReadableDimension getFrameSize() {
|
|
return renderInfo.getFrameSize();
|
|
}
|
|
|
|
@Override
|
|
public int getTotalFrames() {
|
|
return renderInfo.getTotalFrames();
|
|
}
|
|
|
|
@Override
|
|
public float updateForNextFrame() {
|
|
if (call++ % 2 == 0) {
|
|
shaderProgram.stopUsing();
|
|
partialTicks = renderInfo.updateForNextFrame();
|
|
shaderProgram.use();
|
|
}
|
|
return partialTicks;
|
|
}
|
|
|
|
@Override
|
|
public RenderSettings getRenderSettings() {
|
|
return renderInfo.getRenderSettings();
|
|
}
|
|
};
|
|
left = new CubicStereoFrameCapturer(worldRenderer, fakeInfo, frameSize);
|
|
right = new CubicStereoFrameCapturer(worldRenderer, fakeInfo, frameSize);
|
|
try {
|
|
shaderProgram = new Program(vertexResource, fragmentResource);
|
|
shaderProgram.use();
|
|
leftEyeVariable = shaderProgram.getUniformVariable("leftEye");
|
|
directionVariable = shaderProgram.getUniformVariable("direction");
|
|
setTexture("texture", 0);
|
|
setTexture("lightMap", 1);
|
|
linkState(0, "textureEnabled");
|
|
linkState(1, "lightMapEnabled");
|
|
linkState(2, "hurtTextureEnabled");
|
|
final Program.Uniform uniform = shaderProgram.getUniformVariable("fogEnabled");
|
|
previousFogState = GlStateManager.fogState.field_179049_a;
|
|
uniform.set(previousFogState.currentState);
|
|
GlStateManager.fogState.field_179049_a = new BooleanState(previousFogState.capability) {
|
|
@Override
|
|
public void setState(boolean state) {
|
|
super.setState(state);
|
|
uniform.set(state);
|
|
}
|
|
};
|
|
shaderProgram.stopUsing();
|
|
} catch (Exception e) {
|
|
throw new ReportedException(CrashReport.makeCrashReport(e, "Creating ODS shaders"));
|
|
}
|
|
}
|
|
|
|
private void setTexture(String texture, int i) {
|
|
shaderProgram.getUniformVariable(texture).set(i);
|
|
}
|
|
|
|
private void linkState(int id, String var) {
|
|
final Program.Uniform uniform = shaderProgram.getUniformVariable(var);
|
|
previousStates[id] = GlStateManager.textureState[id].texture2DState;
|
|
uniform.set(previousStates[id].currentState);
|
|
GlStateManager.textureState[id].texture2DState = new BooleanState(previousStates[id].capability) {
|
|
@Override
|
|
public void setState(boolean state) {
|
|
super.setState(state);
|
|
uniform.set(state);
|
|
}
|
|
};
|
|
}
|
|
|
|
@Override
|
|
public boolean isDone() {
|
|
return left.isDone() && right.isDone();
|
|
}
|
|
|
|
@Override
|
|
public ODSOpenGlFrame process() {
|
|
shaderProgram.use();
|
|
leftEyeVariable.set(true);
|
|
CubicOpenGlFrame leftFrame = left.process();
|
|
leftEyeVariable.set(false);
|
|
CubicOpenGlFrame rightFrame = right.process();
|
|
shaderProgram.stopUsing();
|
|
|
|
if (leftFrame != null && rightFrame != null) {
|
|
return new ODSOpenGlFrame(leftFrame, rightFrame);
|
|
}
|
|
return null;
|
|
}
|
|
|
|
@Override
|
|
public void close() throws IOException {
|
|
left.close();
|
|
right.close();
|
|
shaderProgram.delete();
|
|
for (int i = 0; i < 3; i++) {
|
|
GlStateManager.textureState[i].texture2DState = previousStates[i];
|
|
}
|
|
GlStateManager.fogState.field_179049_a = previousFogState;
|
|
}
|
|
|
|
private class CubicStereoFrameCapturer extends CubicPboOpenGlFrameCapturer {
|
|
public CubicStereoFrameCapturer(WorldRenderer worldRenderer, RenderInfo renderInfo, int frameSize) {
|
|
super(worldRenderer, renderInfo, frameSize);
|
|
}
|
|
|
|
@Override
|
|
protected OpenGlFrame renderFrame(int frameId, float partialTicks, CubicOpenGlFrameCapturer.Data captureData) {
|
|
resize(getFrameWidth(), getFrameHeight());
|
|
|
|
pushMatrix();
|
|
frameBuffer().bindFramebuffer(true);
|
|
|
|
clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
|
enableTexture2D();
|
|
|
|
directionVariable.set(captureData.ordinal());
|
|
worldRenderer.renderWorld(partialTicks, null);
|
|
|
|
frameBuffer().unbindFramebuffer();
|
|
popMatrix();
|
|
|
|
return captureFrame(frameId, captureData);
|
|
}
|
|
}
|
|
}
|