Rework rendering

Adds default, stereoscopic, tiling, cubic and equirectangular frame rendering
This commit is contained in:
johni0702
2015-05-23 14:56:11 +02:00
parent 361ba73978
commit 18f22f57d0
30 changed files with 2167 additions and 207 deletions

View File

@@ -0,0 +1,109 @@
package eu.crushedpixel.replaymod.video.entity;
import eu.crushedpixel.replaymod.replay.ReplayHandler;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.entity.Entity;
public class CubicEntityRenderer extends CustomEntityRenderer {
public static enum Direction {
TOP(1), BOTTOM(9), LEFT(4), FRONT(5), RIGHT(6), BACK(7);
private final int frame;
Direction(int frame) {
this.frame = frame;
}
public static Direction forFrame(int frame) {
for (Direction d : values()) {
if (d.frame == frame) {
return d;
}
}
return null;
}
public int getCubicFrame() {
return frame;
}
}
private final boolean stable;
private Direction direction;
public CubicEntityRenderer(boolean stable) {
this.stable = stable;
}
public void setFrame(int id) {
setDirection(Direction.forFrame(id));
}
public void setDirection(Direction direction) {
this.direction = direction;
}
@Override
protected void gluPerspective(float fovY, float aspect, float zNear, float zFar) {
super.gluPerspective(90, 1, zNear, zFar);
}
@Override
protected void setupCameraTransform(float partialTicks) {
Entity entity = mc.getRenderViewEntity();
float orgYaw = entity.rotationYaw;
float orgPitch = entity.rotationPitch;
float orgPrevYaw = entity.prevRotationYaw;
float orgPrevPitch = entity.prevRotationPitch;
float orgRoll = ReplayHandler.getCameraTilt();
super.setupCameraTransform(partialTicks);
entity.rotationYaw = orgYaw;
entity.rotationPitch = orgPitch;
entity.prevRotationYaw = orgPrevYaw;
entity.prevRotationPitch = orgPrevPitch;
if (stable) {
ReplayHandler.setCameraTilt(orgRoll);
}
}
@Override
protected void orientCamera(float partialTicks) {
Entity entity = mc.getRenderViewEntity();
// Rotate
switch(direction) {
case FRONT:
GlStateManager.rotate(0, 0.0F, 1.0F, 0.0F);
break;
case RIGHT:
GlStateManager.rotate(90, 0.0F, 1.0F, 0.0F);
break;
case BACK:
GlStateManager.rotate(180, 0.0F, 1.0F, 0.0F);
break;
case LEFT:
GlStateManager.rotate(-90, 0.0F, 1.0F, 0.0F);
break;
case BOTTOM:
GlStateManager.rotate(90, 1.0F, 0.0F, 0.0F);
break;
case TOP:
GlStateManager.rotate(-90, 1.0F, 0.0F, 0.0F);
break;
}
if (stable) {
// Stop the minecraft code from doing any rotation
entity.prevRotationPitch = entity.rotationPitch = 0;
entity.prevRotationYaw = entity.rotationYaw = 0;
ReplayHandler.setCameraTilt(0);
}
// Minecraft goes back a little so we have to invert that
GlStateManager.translate(0.0F, 0.0F, 0.1F);
super.orientCamera(partialTicks);
}
}

View File

@@ -0,0 +1,225 @@
package eu.crushedpixel.replaymod.video.entity;
import net.minecraft.client.Minecraft;
import net.minecraft.client.particle.EffectRenderer;
import net.minecraft.client.renderer.*;
import net.minecraft.client.renderer.culling.ClippingHelperImpl;
import net.minecraft.client.renderer.culling.ICamera;
import net.minecraft.client.renderer.texture.TextureMap;
import net.minecraft.entity.Entity;
import net.minecraft.util.AxisAlignedBB;
import net.minecraft.util.EnumWorldBlockLayer;
import net.minecraft.util.MathHelper;
import org.lwjgl.util.glu.Project;
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;
protected int frameCount;
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);
}
}
}
protected void renderWorld(float partialTicks, long finishTimeNano) {
proxied.updateLightmap(partialTicks);
enableDepth();
enableAlpha();
alphaFunc(516, 0.5F);
renderWorldPass(partialTicks, finishTimeNano, 2);
}
protected void renderWorldPass(float partialTicks, long finishTimeNano, int renderPass) {
RenderGlobal renderglobal = mc.renderGlobal;
EffectRenderer effectrenderer = mc.effectRenderer;
Entity entity = mc.getRenderViewEntity();
enableCull();
viewport(0, 0, mc.displayWidth, mc.displayHeight);
proxied.updateFogColor(partialTicks);
clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
setupCameraTransform(partialTicks);
ActiveRenderInfo.updateRenderInfo(mc.thePlayer, mc.gameSettings.thirdPersonView == 2);
ClippingHelperImpl.getInstance();
ICamera camera = new NoCullingCamera();
if (this.mc.gameSettings.renderDistanceChunks >= 4) {
proxied.setupFog(-1, partialTicks);
matrixMode(GL_PROJECTION);
loadIdentity();
gluPerspective(proxied.getFOVModifier(partialTicks, true), (float) mc.displayWidth / mc.displayHeight, 0.05F, proxied.farPlaneDistance * 2.0F);
matrixMode(GL_MODELVIEW);
renderglobal.renderSky(partialTicks, renderPass);
matrixMode(GL_PROJECTION);
loadIdentity();
gluPerspective(proxied.getFOVModifier(partialTicks, true), (float) mc.displayWidth / mc.displayHeight, 0.05F, proxied.farPlaneDistance * MathHelper.SQRT_2);
matrixMode(GL_MODELVIEW);
}
proxied.setupFog(0, partialTicks);
shadeModel(GL_SMOOTH);
if (entity.posY + entity.getEyeHeight() < 128) {
renderCloudsCheck(renderglobal, partialTicks, renderPass);
}
proxied.setupFog(0, partialTicks);
mc.getTextureManager().bindTexture(TextureMap.locationBlocksTexture);
RenderHelper.disableStandardItemLighting();
renderglobal.setupTerrain(entity, partialTicks, camera, frameCount++, mc.thePlayer.isSpectator());
renderglobal.updateChunks(finishTimeNano);
matrixMode(GL_MODELVIEW);
pushMatrix();
disableAlpha();
renderglobal.renderBlockLayer(EnumWorldBlockLayer.SOLID, partialTicks, renderPass, entity);
enableAlpha();
renderglobal.renderBlockLayer(EnumWorldBlockLayer.CUTOUT_MIPPED, partialTicks, renderPass, entity);
mc.getTextureManager().getTexture(TextureMap.locationBlocksTexture).setBlurMipmap(false, false);
renderglobal.renderBlockLayer(EnumWorldBlockLayer.CUTOUT, partialTicks, renderPass, entity);
mc.getTextureManager().getTexture(TextureMap.locationBlocksTexture).restoreLastBlurMipmap();
shadeModel(GL_FLAT);
alphaFunc(516, 0.1F);
matrixMode(GL_MODELVIEW);
popMatrix();
pushMatrix();
RenderHelper.enableStandardItemLighting();
net.minecraftforge.client.ForgeHooksClient.setRenderPass(0);
renderglobal.renderEntities(entity, camera, partialTicks);
net.minecraftforge.client.ForgeHooksClient.setRenderPass(0);
RenderHelper.disableStandardItemLighting();
proxied.disableLightmap();
matrixMode(GL_MODELVIEW);
popMatrix();
enableBlend();
tryBlendFuncSeparate(770, 1, 1, 0);
renderglobal.drawBlockDamageTexture(Tessellator.getInstance(), Tessellator.getInstance().getWorldRenderer(), entity, partialTicks);
disableBlend();
proxied.enableLightmap();
effectrenderer.renderLitParticles(entity, partialTicks);
RenderHelper.disableStandardItemLighting();
proxied.setupFog(0, partialTicks);
effectrenderer.renderParticles(entity, partialTicks);
proxied.disableLightmap();
depthMask(false);
enableCull();
proxied.renderRainSnow(partialTicks);
depthMask(true);
renderglobal.renderWorldBorder(entity, partialTicks);
disableBlend();
enableCull();
tryBlendFuncSeparate(770, 771, 1, 0);
alphaFunc(516, 0.1F);
proxied.setupFog(0, partialTicks);
enableBlend();
depthMask(false);
mc.getTextureManager().bindTexture(TextureMap.locationBlocksTexture);
shadeModel(GL_SMOOTH);
if (mc.gameSettings.fancyGraphics) {
enableBlend();
tryBlendFuncSeparate(770, 771, 1, 0);
renderglobal.renderBlockLayer(EnumWorldBlockLayer.TRANSLUCENT, partialTicks, renderPass, entity);
disableBlend();
} else {
renderglobal.renderBlockLayer(EnumWorldBlockLayer.TRANSLUCENT, partialTicks, renderPass, entity);
}
RenderHelper.enableStandardItemLighting();
net.minecraftforge.client.ForgeHooksClient.setRenderPass(1);
renderglobal.renderEntities(entity, camera, partialTicks);
net.minecraftforge.client.ForgeHooksClient.setRenderPass(-1);
RenderHelper.disableStandardItemLighting();
shadeModel(GL_FLAT);
depthMask(true);
enableCull();
disableBlend();
disableFog();
if (entity.posY + entity.getEyeHeight() >= 128) {
renderCloudsCheck(renderglobal, partialTicks, renderPass);
}
net.minecraftforge.client.ForgeHooksClient.dispatchRenderLast(renderglobal, partialTicks);
}
protected void setupCameraTransform(float partialTicks) {
proxied.farPlaneDistance = (float)(this.mc.gameSettings.renderDistanceChunks * 16);
matrixMode(GL_PROJECTION);
loadIdentity();
gluPerspective(proxied.getFOVModifier(partialTicks, true), (float) this.mc.displayWidth / (float) this.mc.displayHeight, 0.05F, proxied.farPlaneDistance * MathHelper.SQRT_2);
matrixMode(GL_MODELVIEW);
loadIdentity();
orientCamera(partialTicks);
}
protected void orientCamera(float partialTicks) {
proxied.orientCamera(partialTicks);
}
protected void renderCloudsCheck(RenderGlobal renderglobal, float partialTicks, int renderPass) {
if (this.mc.gameSettings.shouldRenderClouds()) {
matrixMode(GL_PROJECTION);
loadIdentity();
gluPerspective(proxied.getFOVModifier(partialTicks, true), (float) this.mc.displayWidth / (float) this.mc.displayHeight, 0.05F, proxied.farPlaneDistance * 4.0F);
matrixMode(GL_MODELVIEW);
pushMatrix();
proxied.setupFog(0, partialTicks);
renderglobal.renderClouds(partialTicks, renderPass);
disableFog();
popMatrix();
matrixMode(GL_PROJECTION);
loadIdentity();
gluPerspective(proxied.getFOVModifier(partialTicks, true), (float)this.mc.displayWidth / (float)this.mc.displayHeight, 0.05F, proxied.farPlaneDistance * MathHelper.SQRT_2);
matrixMode(GL_MODELVIEW);
}
}
public static final class NoCullingCamera implements ICamera {
@Override
public boolean isBoundingBoxInFrustum(AxisAlignedBB p_78546_1_) {
return true;
}
@Override
public void setPosition(double p_78547_1_, double p_78547_3_, double p_78547_5_) {
}
}
}

View File

@@ -0,0 +1,39 @@
package eu.crushedpixel.replaymod.video.entity;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.util.MathHelper;
import static net.minecraft.client.renderer.GlStateManager.loadIdentity;
import static net.minecraft.client.renderer.GlStateManager.matrixMode;
import static org.lwjgl.opengl.GL11.GL_MODELVIEW;
import static org.lwjgl.opengl.GL11.GL_PROJECTION;
public class StereoscopicEntityRenderer extends CustomEntityRenderer {
private boolean leftEye;
public void setEye(boolean leftEye) {
this.leftEye = leftEye;
}
protected void translateStereoscopic() {
GlStateManager.translate(leftEye ? 0.07 : -0.07, 0, 0);
}
@Override
protected void setupCameraTransform(float partialTicks) {
proxied.farPlaneDistance = (float)(this.mc.gameSettings.renderDistanceChunks * 16);
matrixMode(GL_PROJECTION);
loadIdentity();
translateStereoscopic();
gluPerspective(proxied.getFOVModifier(partialTicks, true), (float) this.mc.displayWidth / (float) this.mc.displayHeight, 0.05F, proxied.farPlaneDistance * MathHelper.SQRT_2);
matrixMode(GL_MODELVIEW);
loadIdentity();
translateStereoscopic();
orientCamera(partialTicks);
}
}

View File

@@ -0,0 +1,41 @@
package eu.crushedpixel.replaymod.video.entity;
import eu.crushedpixel.replaymod.video.frame.TilingFrameRenderer;
import static net.minecraft.client.renderer.GlStateManager.scale;
import static net.minecraft.client.renderer.GlStateManager.translate;
import static org.lwjgl.opengl.GL11.glFrustum;
public class TilingEntityRenderer extends CustomEntityRenderer {
private final TilingFrameRenderer renderer;
private int tileX, tileY;
public TilingEntityRenderer(TilingFrameRenderer renderer) {
this.renderer = renderer;
}
public void setTile(int tileX, int tileY) {
this.tileX = tileX;
this.tileY = tileY;
}
@Override
public void gluPerspective(float fovY, float aspect, float zNear, float zFar) {
double height = Math.tan(fovY / 360 * Math.PI) * zNear;
double width = height * aspect;
int videoWidth = renderer.getVideoWidth();
int videoHeight = renderer.getVideoHeight();
int tileWidth = renderer.getTileWidth();
int tileHeight = renderer.getTileHeight();
double tilesX = (double) videoWidth / tileWidth;
double tilesY = (double) videoHeight / tileHeight;
double tilesMin = Math.min(tilesX, tilesY);
scale(tilesMin, tilesMin, 1);
double xOffset = (2 * tileX - tilesX + 1) / tilesMin;
double yOffset = (2 * tileY - tilesY + 1) / tilesMin;
translate(-xOffset, yOffset, 0);
glFrustum(-width, width, -height, height, zNear, zFar);
}
}