0ba5b0aMerge branch '1.8-shaders' into 1.8e5eb982Add Optifine compatibility to rendering by disabling their separate chunk loading queue Add compatibility to shaders that utilize the Shadow Map by manually setting displayListEntitiesDirty to false Call Shaders.beginRender in an Event Handler to avoid calling all of EntityRenderer#renderWorld3a28c5bDraw the GuiVideoRenderer on a separate framebuffer that has the actual size of the window instead of MC's framebuffer which may have a different size636ce7bAdd compatibility for GLSL Shaders92eb11aChange video preview to be compatible with Optifine
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.fog;
|
|
uniform.set(previousFogState.currentState);
|
|
GlStateManager.fogState.fog = 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.fog = 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);
|
|
}
|
|
}
|
|
}
|