From 18ec3cccc5ebd6d7dfe72ce8211a347be18186cc Mon Sep 17 00:00:00 2001 From: johni0702 Date: Sun, 28 Jun 2015 17:53:46 +0200 Subject: [PATCH] =?UTF-8?q?Realign=20all=20particles=20towards=20the=20cam?= =?UTF-8?q?era=20when=20rendering=20360=C2=B0=20frames?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../video/entity/CubicEntityRenderer.java | 21 ++++ .../video/entity/CustomEntityRenderer.java | 106 ++++++++++++++++-- src/main/resources/META-INF/replaymod_at.cfg | 4 + 3 files changed, 124 insertions(+), 7 deletions(-) diff --git a/src/main/java/eu/crushedpixel/replaymod/video/entity/CubicEntityRenderer.java b/src/main/java/eu/crushedpixel/replaymod/video/entity/CubicEntityRenderer.java index db289765..c52ed1e5 100644 --- a/src/main/java/eu/crushedpixel/replaymod/video/entity/CubicEntityRenderer.java +++ b/src/main/java/eu/crushedpixel/replaymod/video/entity/CubicEntityRenderer.java @@ -2,7 +2,9 @@ package eu.crushedpixel.replaymod.video.entity; import eu.crushedpixel.replaymod.replay.ReplayHandler; import eu.crushedpixel.replaymod.settings.RenderOptions; +import net.minecraft.client.particle.EntityFX; import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.client.renderer.WorldRenderer; import net.minecraft.entity.Entity; import net.minecraft.util.ResourceLocation; @@ -123,4 +125,23 @@ public class CubicEntityRenderer extends CustomEntityRenderer { protected void renderSpectatorHand(float partialTicks, int renderPass) { // No spectator hands during 360° view } + + @Override + protected void renderParticle(EntityFX fx, WorldRenderer worldRenderer, Entity view, float partialTicks, float rotX, float rotXZ, float rotZ, float rotYZ, float rotXY) { + // Align all particles towards the camera + double dx = fx.prevPosX + (fx.posX - fx.prevPosX) * partialTicks - view.posX; + double dy = fx.prevPosY + (fx.posY - fx.prevPosY) * partialTicks - view.posY; + double dz = fx.prevPosZ + (fx.posZ - fx.prevPosZ) * partialTicks - view.posZ; + double pitch = -Math.atan2(dy, Math.sqrt(dx * dx + dz * dz)); + double yaw = -Math.atan2(dx, dz); + + rotX = (float) Math.cos(yaw); + rotZ = (float) Math.sin(yaw); + rotXZ = (float) Math.cos(pitch); + + rotYZ = (float) (-rotZ * Math.sin(pitch)); + rotXY = (float) (rotX * Math.sin(pitch)); + + super.renderParticle(fx, worldRenderer, view, partialTicks, rotX, rotXZ, rotZ, rotYZ, rotXY); + } } diff --git a/src/main/java/eu/crushedpixel/replaymod/video/entity/CustomEntityRenderer.java b/src/main/java/eu/crushedpixel/replaymod/video/entity/CustomEntityRenderer.java index dc6f800a..37db150f 100644 --- a/src/main/java/eu/crushedpixel/replaymod/video/entity/CustomEntityRenderer.java +++ b/src/main/java/eu/crushedpixel/replaymod/video/entity/CustomEntityRenderer.java @@ -7,9 +7,11 @@ 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.particle.EntityFX; 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.TextureManager; import net.minecraft.client.renderer.texture.TextureMap; import net.minecraft.entity.Entity; import net.minecraft.entity.player.EntityPlayer; @@ -21,6 +23,7 @@ import org.lwjgl.util.glu.Project; import java.awt.image.BufferedImage; import java.lang.reflect.Field; +import java.util.List; import static net.minecraft.client.renderer.GlStateManager.*; import static org.lwjgl.opengl.GL11.*; @@ -135,7 +138,6 @@ public abstract class CustomEntityRenderer { 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); @@ -209,12 +211,7 @@ public abstract class CustomEntityRenderer { renderglobal.drawBlockDamageTexture(Tessellator.getInstance(), Tessellator.getInstance().getWorldRenderer(), entity, partialTicks); disableBlend(); - proxied.enableLightmap(); - effectrenderer.renderLitParticles(entity, partialTicks); - RenderHelper.disableStandardItemLighting(); - setupFog(0, partialTicks); - effectrenderer.renderParticles(entity, partialTicks); - proxied.disableLightmap(); + renderParticles(entity, partialTicks); depthMask(false); enableCull(); @@ -261,6 +258,101 @@ public abstract class CustomEntityRenderer { renderSpectatorHand(partialTicks, renderPass); } + protected void renderParticles(Entity entity, float partialTicks) { + proxied.enableLightmap(); + renderLitParticles(entity, partialTicks); + RenderHelper.disableStandardItemLighting(); + setupFog(0, partialTicks); + renderNormalParticles(entity, partialTicks); + proxied.disableLightmap(); + } + + protected void renderLitParticles(Entity entity, float partialTicks) { + EffectRenderer effectRenderer = mc.effectRenderer; + Tessellator tessellator = Tessellator.getInstance(); + WorldRenderer worldrenderer = tessellator.getWorldRenderer(); + + double yaw = Math.toRadians(entity.rotationYaw); + double pitch = Math.toRadians(entity.rotationPitch); + + float rotX = (float) Math.cos(yaw); + float rotZ = (float) Math.sin(yaw); + float rotXZ = (float) Math.cos(pitch); + + float rotYZ = (float) (-rotZ * Math.sin(pitch)); + float rotXY = (float) (rotX * Math.sin(pitch)); + + for (int i = 0; i < 2; i++) { + @SuppressWarnings("unchecked") + List list = (List) effectRenderer.fxLayers[3][i]; + for (EntityFX fx : list) { + worldrenderer.setBrightness(fx.getBrightnessForRender(partialTicks)); + renderParticle(fx, worldrenderer, entity, partialTicks, rotX, rotXZ, rotZ, rotYZ, rotXY); + } + } + } + + protected void renderNormalParticles(Entity entity, float partialTicks) { + EffectRenderer effectRenderer = mc.effectRenderer; + TextureManager textureManager = mc.getTextureManager(); + Tessellator tessellator = Tessellator.getInstance(); + WorldRenderer worldRenderer = tessellator.getWorldRenderer(); + + float rotX = ActiveRenderInfo.getRotationX(); + float rotZ = ActiveRenderInfo.getRotationZ(); + float rotYZ = ActiveRenderInfo.getRotationYZ(); + float rotXY = ActiveRenderInfo.getRotationXY(); + float rotXZ = ActiveRenderInfo.getRotationXZ(); + EntityFX.interpPosX = entity.posX; + EntityFX.interpPosY = entity.posY; + EntityFX.interpPosZ = entity.posZ; + + enableBlend(); + blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + alphaFunc(GL_GREATER, 0.003921569F); + + for (int texture = 0; texture < 3; texture++) { + for (int depthMask = 0; depthMask < 2; depthMask++) { + if (effectRenderer.fxLayers[texture][depthMask].isEmpty()) { + continue; + } + + if (depthMask == 0) { + GlStateManager.depthMask(false); + } else { + GlStateManager.depthMask(true); + } + + if (texture == 1) { + textureManager.bindTexture(TextureMap.locationBlocksTexture); + } else { + textureManager.bindTexture(EffectRenderer.particleTextures); + } + + color(1, 1, 1, 1); + worldRenderer.startDrawingQuads(); + + @SuppressWarnings("unchecked") + List list = (List) effectRenderer.fxLayers[texture][depthMask]; + for (final EntityFX fx : list) { + worldRenderer.setBrightness(fx.getBrightnessForRender(partialTicks)); + renderParticle(fx, worldRenderer, entity, partialTicks, rotX, rotXZ, rotZ, rotYZ, rotXY); + } + + tessellator.draw(); + } + } + + depthMask(true); + disableBlend(); + alphaFunc(516, 0.1F); + } + + protected void renderParticle(EntityFX fx, WorldRenderer worldRenderer, Entity view, float partialTicks, + float rotX, float rotXZ, float rotZ, float rotYZ, float rotXY) { + fx.func_180434_a(worldRenderer, view, partialTicks, rotX, rotXZ, rotZ, rotYZ, rotXY); + } + protected void renderSpectatorHand(float partialTicks, int renderPass) { Entity currentEntity = ReplayHandler.getCurrentEntity(); if(!ReplayHandler.isCamera() && currentEntity instanceof EntityPlayer) { diff --git a/src/main/resources/META-INF/replaymod_at.cfg b/src/main/resources/META-INF/replaymod_at.cfg index b7f3c6ae..0103ff0e 100644 --- a/src/main/resources/META-INF/replaymod_at.cfg +++ b/src/main/resources/META-INF/replaymod_at.cfg @@ -87,5 +87,9 @@ public net.minecraft.client.renderer.ItemRenderer *() # EntityOtherPlayerMP public net.minecraft.client.entity.EntityOtherPlayerMP * +# EffectRenderer +public net.minecraft.client.particle.EffectRenderer field_110737_b # particleTextures +public net.minecraft.client.particle.EffectRenderer field_78876_b # fxLayers + # Example # public net.minecraft.package.ClassName func_some_id(Ljava/lang/Class;IZS)V # methodName