Replace CustomEntityHandler with mixin magic
This commit is contained in:
47
build.gradle
47
build.gradle
@@ -23,6 +23,11 @@ version = "0.6"
|
|||||||
group= "eu.crushedpixel.replaymod"
|
group= "eu.crushedpixel.replaymod"
|
||||||
archivesBaseName = "replaymod"
|
archivesBaseName = "replaymod"
|
||||||
|
|
||||||
|
ext {
|
||||||
|
mixinSrg = new File(project.buildDir, 'tmp/mixins/mixins.srg')
|
||||||
|
mixinRefMap = new File(project.buildDir, 'tmp/mixins/mixins.replaymod.refmap.json')
|
||||||
|
}
|
||||||
|
|
||||||
minecraft {
|
minecraft {
|
||||||
version = "1.8-11.14.1.1402"
|
version = "1.8-11.14.1.1402"
|
||||||
runDir = "eclipse"
|
runDir = "eclipse"
|
||||||
@@ -35,6 +40,13 @@ minecraft {
|
|||||||
mappings = "snapshot_nodoc_20141130"
|
mappings = "snapshot_nodoc_20141130"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
maven {
|
||||||
|
name = "SpongePowered Repo"
|
||||||
|
url = "http://repo.spongepowered.org/maven/"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
configurations {
|
configurations {
|
||||||
shade
|
shade
|
||||||
compile.extendsFrom shade
|
compile.extendsFrom shade
|
||||||
@@ -43,6 +55,7 @@ configurations {
|
|||||||
dependencies {
|
dependencies {
|
||||||
compile 'org.projectlombok:lombok:1.16.4'
|
compile 'org.projectlombok:lombok:1.16.4'
|
||||||
|
|
||||||
|
shade 'org.spongepowered:mixin:0.4.3'
|
||||||
shade fileTree(dir: 'libs', includes: ['*.jar'])
|
shade fileTree(dir: 'libs', includes: ['*.jar'])
|
||||||
// you may put jars on which you depend on in ./libs
|
// you may put jars on which you depend on in ./libs
|
||||||
// or you may define them like so..
|
// or you may define them like so..
|
||||||
@@ -61,6 +74,9 @@ dependencies {
|
|||||||
|
|
||||||
jar {
|
jar {
|
||||||
dependsOn configurations.shade
|
dependsOn configurations.shade
|
||||||
|
|
||||||
|
from project.mixinRefMap
|
||||||
|
|
||||||
def noticeDir = file("$buildDir/NOTICE")
|
def noticeDir = file("$buildDir/NOTICE")
|
||||||
doFirst {
|
doFirst {
|
||||||
noticeDir.deleteDir()
|
noticeDir.deleteDir()
|
||||||
@@ -97,8 +113,10 @@ jar {
|
|||||||
}
|
}
|
||||||
|
|
||||||
manifest {
|
manifest {
|
||||||
attributes 'FMLCorePlugin': 'eu.crushedpixel.replaymod.coremod.LoadingPlugin',
|
attributes 'TweakClass': 'org.spongepowered.asm.launch.MixinTweaker',
|
||||||
'FMLCorePluginContainsFMLMod': 'false',
|
'TweakOrder': '0',
|
||||||
|
'MixinConfigs': 'mixins.replaymod.json',
|
||||||
|
'FMLCorePlugin': 'eu.crushedpixel.replaymod.coremod.LoadingPlugin',
|
||||||
'FMLAT': 'replaymod_at.cfg'
|
'FMLAT': 'replaymod_at.cfg'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -140,4 +158,29 @@ sourceSets {
|
|||||||
main { output.resourcesDir = output.classesDir }
|
main { output.resourcesDir = output.classesDir }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
reobf.doFirst {
|
||||||
|
if (project.mixinSrg.exists()) {
|
||||||
|
addExtraSrgFile project.mixinSrg
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
task copySrgs(type: Copy, dependsOn: 'genSrgs') {
|
||||||
|
from plugins.getPlugin('forge').delayedFile('{SRG_DIR}')
|
||||||
|
|
||||||
|
include '**/*.srg'
|
||||||
|
into 'build/srgs'
|
||||||
|
}
|
||||||
|
|
||||||
|
setupDecompWorkspace.dependsOn copySrgs
|
||||||
|
setupDevWorkspace.dependsOn copySrgs
|
||||||
|
compileJava.dependsOn copySrgs
|
||||||
|
|
||||||
|
compileJava {
|
||||||
|
options.compilerArgs += [
|
||||||
|
"-AoutSrgFile=${project.mixinSrg.canonicalPath}",
|
||||||
|
"-AoutRefMapFile=${project.mixinRefMap.canonicalPath}",
|
||||||
|
"-AreobfSrgFile=${project.file('build/srgs/mcp-srg.srg').canonicalPath}"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
defaultTasks 'build'
|
defaultTasks 'build'
|
||||||
@@ -1,128 +0,0 @@
|
|||||||
package eu.crushedpixel.replaymod.coremod;
|
|
||||||
|
|
||||||
import net.minecraft.launchwrapper.IClassTransformer;
|
|
||||||
import org.objectweb.asm.ClassReader;
|
|
||||||
import org.objectweb.asm.ClassWriter;
|
|
||||||
import org.objectweb.asm.tree.*;
|
|
||||||
|
|
||||||
import static org.objectweb.asm.Opcodes.*;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Transforms the EntityRenderer class:
|
|
||||||
* - Adds a new field 'CustomEntityRenderer hook'
|
|
||||||
* - Moves code of 'loadShader' into 'loadShader$Original'
|
|
||||||
* - Creates 'loadShader' method (see {@link #createLoadShader(ClassNode, MethodNode)} ()}
|
|
||||||
*
|
|
||||||
* Transforms the CustomEntityRenderer class:
|
|
||||||
* - Method 'original_loadShader' calls 'loadShader$Original'
|
|
||||||
*/
|
|
||||||
public class EntityRendererCT implements IClassTransformer {
|
|
||||||
|
|
||||||
private static final String HOOK = "eu.crushedpixel.replaymod.video.entity.CustomEntityRenderer";
|
|
||||||
private static final String HOOK_JVM = HOOK.replace('.', '/');
|
|
||||||
private static final String HOOK_TYPE = "L" + HOOK_JVM + ";";
|
|
||||||
private static final String ENTITY_RENDERER = "net.minecraft.client.renderer.EntityRenderer";
|
|
||||||
private static final String ENTITY_RENDERER_JVM = ENTITY_RENDERER.replace('.', '/');
|
|
||||||
private static final String ENTITY_RENDERER_TYPE = "L" + ENTITY_RENDERER_JVM + ";";
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public byte[] transform(String name, String transformedName, byte[] bytes) {
|
|
||||||
if (ENTITY_RENDERER.equals(transformedName)) {
|
|
||||||
if (name.equals(transformedName)) {
|
|
||||||
return transformEntityRenderer(bytes, "loadShader", "(Lnet/minecraft/util/ResourceLocation;)V");
|
|
||||||
} else {
|
|
||||||
return transformEntityRenderer(bytes, "a", "(Loa;)V");
|
|
||||||
}
|
|
||||||
} else if (HOOK.equals(transformedName)) {
|
|
||||||
return transformHook(bytes);
|
|
||||||
}
|
|
||||||
return bytes;
|
|
||||||
}
|
|
||||||
|
|
||||||
private byte[] transformHook(byte[] bytes) {
|
|
||||||
ClassReader classReader = new ClassReader(bytes);
|
|
||||||
ClassNode classNode = new ClassNode();
|
|
||||||
classReader.accept(classNode, 0);
|
|
||||||
|
|
||||||
// Find method
|
|
||||||
for (MethodNode m : classNode.methods) {
|
|
||||||
if ("original_loadShader".equals(m.name)) {
|
|
||||||
m.instructions.clear();
|
|
||||||
InsnList iter = m.instructions;
|
|
||||||
iter.add(new VarInsnNode(ALOAD, 0)); // this
|
|
||||||
iter.add(new FieldInsnNode(GETFIELD, classNode.name, "proxied", ENTITY_RENDERER_TYPE));
|
|
||||||
iter.add(new VarInsnNode(ALOAD, 1)); // resourceLocation
|
|
||||||
iter.add(new MethodInsnNode(INVOKEVIRTUAL, ENTITY_RENDERER_JVM, "loadShader$Original", m.desc, false));
|
|
||||||
iter.add(new InsnNode(RETURN));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_MAXS);
|
|
||||||
classNode.accept(classWriter);
|
|
||||||
return classWriter.toByteArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
private byte[] transformEntityRenderer(byte[] bytes, String name_loadShader, String desc_loadShader) {
|
|
||||||
ClassReader classReader = new ClassReader(bytes);
|
|
||||||
ClassNode classNode = new ClassNode();
|
|
||||||
classReader.accept(classNode, 0);
|
|
||||||
|
|
||||||
// Add field
|
|
||||||
classNode.visitField(ACC_PUBLIC, "hook", HOOK_TYPE, null, null);
|
|
||||||
|
|
||||||
// Find method
|
|
||||||
MethodNode setupTerrain = null;
|
|
||||||
for (MethodNode m : classNode.methods) {
|
|
||||||
if (name_loadShader.equals(m.name) && desc_loadShader.equals(m.desc)) {
|
|
||||||
setupTerrain = m;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (setupTerrain == null) {
|
|
||||||
throw new NoSuchMethodError("loadShader");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generate new method
|
|
||||||
classNode.methods.add(createLoadShader(classNode, setupTerrain));
|
|
||||||
|
|
||||||
// Rename original method
|
|
||||||
setupTerrain.name = "loadShader$Original";
|
|
||||||
setupTerrain.access = ACC_PUBLIC;
|
|
||||||
|
|
||||||
ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_MAXS);
|
|
||||||
classNode.accept(classWriter);
|
|
||||||
return classWriter.toByteArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* public void loadShader(ResourceLocation resourceLocation) {
|
|
||||||
* if (this.hook == null) {
|
|
||||||
* loadShader$Original(resourceLocation);
|
|
||||||
* return;
|
|
||||||
* }
|
|
||||||
* hook.loadShader(resourceLocation);
|
|
||||||
* }
|
|
||||||
*/
|
|
||||||
private MethodNode createLoadShader(ClassNode classNode, MethodNode org) {
|
|
||||||
MethodNode method = new MethodNode(org.access, org.name, org.desc, org.signature, new String[0]);
|
|
||||||
InsnList list = method.instructions;
|
|
||||||
list.add(new VarInsnNode(ALOAD, 0));
|
|
||||||
list.add(new FieldInsnNode(GETFIELD, classNode.name, "hook", HOOK_TYPE));
|
|
||||||
LabelNode labelNotNull = new LabelNode();
|
|
||||||
list.add(new JumpInsnNode(IFNONNULL, labelNotNull));
|
|
||||||
|
|
||||||
list.add(new VarInsnNode(ALOAD, 0)); // this
|
|
||||||
list.add(new VarInsnNode(ALOAD, 1)); // resourceLocation
|
|
||||||
list.add(new MethodInsnNode(INVOKEVIRTUAL, classNode.name, "loadShader$Original", org.desc, false));
|
|
||||||
list.add(new InsnNode(RETURN));
|
|
||||||
|
|
||||||
list.add(labelNotNull);
|
|
||||||
list.add(new FrameNode(F_SAME, 0, null, 0, null));
|
|
||||||
list.add(new VarInsnNode(ALOAD, 0)); // this
|
|
||||||
list.add(new FieldInsnNode(GETFIELD, classNode.name, "hook", HOOK_TYPE));
|
|
||||||
list.add(new VarInsnNode(ALOAD, 1)); // resourceLocation
|
|
||||||
list.add(new MethodInsnNode(INVOKEVIRTUAL, HOOK_JVM, "loadShader", org.desc, false));
|
|
||||||
list.add(new InsnNode(RETURN));
|
|
||||||
|
|
||||||
return method;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,19 +1,48 @@
|
|||||||
package eu.crushedpixel.replaymod.coremod;
|
package eu.crushedpixel.replaymod.coremod;
|
||||||
|
|
||||||
|
import net.minecraftforge.fml.relauncher.CoreModManager;
|
||||||
import net.minecraftforge.fml.relauncher.IFMLLoadingPlugin;
|
import net.minecraftforge.fml.relauncher.IFMLLoadingPlugin;
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.spongepowered.asm.launch.MixinBootstrap;
|
||||||
|
import org.spongepowered.asm.mixin.MixinEnvironment;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.security.CodeSource;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public class LoadingPlugin implements IFMLLoadingPlugin {
|
public class LoadingPlugin implements IFMLLoadingPlugin {
|
||||||
|
|
||||||
|
public LoadingPlugin() {
|
||||||
|
MixinBootstrap.init();
|
||||||
|
MixinEnvironment.getDefaultEnvironment().addConfiguration("mixins.replaymod.json");
|
||||||
|
|
||||||
|
CodeSource codeSource = getClass().getProtectionDomain().getCodeSource();
|
||||||
|
if (codeSource != null) {
|
||||||
|
URL location = codeSource.getLocation();
|
||||||
|
try {
|
||||||
|
File file = new File(location.toURI());
|
||||||
|
if (file.isFile()) {
|
||||||
|
// This forces forge to reexamine the jar file for FML mods
|
||||||
|
// Should eventually be handled by Mixin itself, maybe?
|
||||||
|
CoreModManager.getLoadedCoremods().remove(file.getName());
|
||||||
|
}
|
||||||
|
} catch (URISyntaxException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
LogManager.getLogger().warn("No CodeSource, if this is not a development environment we might run into problems!");
|
||||||
|
LogManager.getLogger().warn(getClass().getProtectionDomain());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String[] getASMTransformerClass() {
|
public String[] getASMTransformerClass() {
|
||||||
return new String[]{
|
return new String[]{
|
||||||
CameraRollCT.class.getName(),
|
CameraRollCT.class.getName(),
|
||||||
ForceChunkLoadingCT.class.getName(),
|
ForceChunkLoadingCT.class.getName(),
|
||||||
EntityRendererCT.class.getName(),
|
|
||||||
NoNameTagCT.class.getName(),
|
NoNameTagCT.class.getName(),
|
||||||
RenderManagerCT.class.getName(),
|
|
||||||
SoundManagerCT.class.getName(),
|
SoundManagerCT.class.getName(),
|
||||||
EnchantmentTimerCT.class.getName()
|
EnchantmentTimerCT.class.getName()
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,81 +0,0 @@
|
|||||||
package eu.crushedpixel.replaymod.coremod;
|
|
||||||
|
|
||||||
import net.minecraft.launchwrapper.IClassTransformer;
|
|
||||||
import org.objectweb.asm.ClassReader;
|
|
||||||
import org.objectweb.asm.ClassWriter;
|
|
||||||
import org.objectweb.asm.tree.*;
|
|
||||||
|
|
||||||
import java.util.ListIterator;
|
|
||||||
|
|
||||||
import static org.objectweb.asm.Opcodes.*;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Transforms the RenderManager class:
|
|
||||||
* - Adds a new field 'CubicEntityRenderer hook'
|
|
||||||
* - Injects CubicEntityRenderer.beforeEntityRender(dx, dy, dz) call at beginning of 'doRenderEntity'
|
|
||||||
*/
|
|
||||||
public class RenderManagerCT implements IClassTransformer {
|
|
||||||
|
|
||||||
private static final String HOOK = "eu.crushedpixel.replaymod.video.entity.CubicEntityRenderer";
|
|
||||||
private static final String HOOK_JVM = HOOK.replace('.', '/');
|
|
||||||
private static final String HOOK_TYPE = "L" + HOOK_JVM + ";";
|
|
||||||
private static final String RENDER_MANAGER = "net.minecraft.client.renderer.entity.RenderManager";
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public byte[] transform(String name, String transformedName, byte[] bytes) {
|
|
||||||
if (RENDER_MANAGER.equals(transformedName)) {
|
|
||||||
if (name.equals(transformedName)) {
|
|
||||||
return transformRenderManager(bytes, "doRenderEntity", "(Lnet/minecraft/entity/Entity;DDDFFZ)Z");
|
|
||||||
} else {
|
|
||||||
return transformRenderManager(bytes, "a", "(Lwv;DDDFFZ)Z");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return bytes;
|
|
||||||
}
|
|
||||||
|
|
||||||
private byte[] transformRenderManager(byte[] bytes, String name_doRenderEntity, String desc_doRenderEntity) {
|
|
||||||
ClassReader classReader = new ClassReader(bytes);
|
|
||||||
ClassNode classNode = new ClassNode();
|
|
||||||
classReader.accept(classNode, 0);
|
|
||||||
|
|
||||||
// Add field
|
|
||||||
classNode.visitField(ACC_PUBLIC, "hook", HOOK_TYPE, null, null);
|
|
||||||
|
|
||||||
// Find method
|
|
||||||
MethodNode doRenderEntity = null;
|
|
||||||
for (MethodNode m : classNode.methods) {
|
|
||||||
if (name_doRenderEntity.equals(m.name) && desc_doRenderEntity.equals(m.desc)) {
|
|
||||||
doRenderEntity = m;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (doRenderEntity == null) {
|
|
||||||
throw new NoSuchMethodError("doRenderEntity");
|
|
||||||
}
|
|
||||||
|
|
||||||
injectDoRenderEntity(classNode, doRenderEntity);
|
|
||||||
|
|
||||||
ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_MAXS);
|
|
||||||
classNode.accept(classWriter);
|
|
||||||
return classWriter.toByteArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
private MethodNode injectDoRenderEntity(ClassNode classNode, MethodNode method) {
|
|
||||||
ListIterator<AbstractInsnNode> list = method.instructions.iterator();
|
|
||||||
list.add(new VarInsnNode(ALOAD, 0));
|
|
||||||
list.add(new FieldInsnNode(GETFIELD, classNode.name, "hook", HOOK_TYPE));
|
|
||||||
LabelNode labelNull = new LabelNode();
|
|
||||||
list.add(new JumpInsnNode(IFNULL, labelNull));
|
|
||||||
|
|
||||||
list.add(new VarInsnNode(ALOAD, 0)); // this
|
|
||||||
list.add(new FieldInsnNode(GETFIELD, classNode.name, "hook", HOOK_TYPE));
|
|
||||||
list.add(new VarInsnNode(DLOAD, 2)); // x
|
|
||||||
list.add(new VarInsnNode(DLOAD, 4)); // y
|
|
||||||
list.add(new VarInsnNode(DLOAD, 6)); // z
|
|
||||||
list.add(new MethodInsnNode(INVOKEVIRTUAL, HOOK_JVM, "beforeEntityRender", "(DDD)V", false));
|
|
||||||
|
|
||||||
list.add(labelNull);
|
|
||||||
list.add(new FrameNode(F_SAME, 0, null, 0, null));
|
|
||||||
|
|
||||||
return method;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
package eu.crushedpixel.replaymod.mixin;
|
||||||
|
|
||||||
|
import eu.crushedpixel.replaymod.video.EntityRendererHandler;
|
||||||
|
import eu.crushedpixel.replaymod.video.capturer.CubicOpenGlFrameCapturer;
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.client.particle.EffectRenderer;
|
||||||
|
import net.minecraft.client.particle.EntityFX;
|
||||||
|
import net.minecraft.client.renderer.WorldRenderer;
|
||||||
|
import net.minecraft.entity.Entity;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||||
|
|
||||||
|
@Mixin(EffectRenderer.class)
|
||||||
|
public class MixinEffectRenderer {
|
||||||
|
@Redirect(method = "renderParticles", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/particle/EntityFX;func_180434_a(Lnet/minecraft/client/renderer/WorldRenderer;Lnet/minecraft/entity/Entity;FFFFFF)V"))
|
||||||
|
private void renderNormalParticle(EntityFX fx, WorldRenderer worldRenderer, Entity view, float partialTicks,
|
||||||
|
float rotX, float rotXZ, float rotZ, float rotYZ, float rotXY) {
|
||||||
|
renderParticle(fx, worldRenderer, view, partialTicks, rotX, rotXZ, rotZ, rotYZ, rotXY);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Redirect(method = "renderLitParticles", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/particle/EntityFX;func_180434_a(Lnet/minecraft/client/renderer/WorldRenderer;Lnet/minecraft/entity/Entity;FFFFFF)V"))
|
||||||
|
private void renderLitParticle(EntityFX fx, WorldRenderer worldRenderer, Entity view, float partialTicks,
|
||||||
|
float rotX, float rotXZ, float rotZ, float rotYZ, float rotXY) {
|
||||||
|
renderParticle(fx, worldRenderer, view, partialTicks, rotX, rotXZ, rotZ, rotYZ, rotXY);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void renderParticle(EntityFX fx, WorldRenderer worldRenderer, Entity view, float partialTicks,
|
||||||
|
float rotX, float rotXZ, float rotZ, float rotYZ, float rotXY) {
|
||||||
|
EntityRendererHandler handler = ((EntityRendererHandler.IEntityRenderer) Minecraft.getMinecraft().entityRenderer).getHandler();
|
||||||
|
if (handler != null && handler.data instanceof CubicOpenGlFrameCapturer.Data) {
|
||||||
|
// 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));
|
||||||
|
}
|
||||||
|
fx.func_180434_a(worldRenderer, view, partialTicks, rotX, rotXZ, rotZ, rotYZ, rotXY);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,237 @@
|
|||||||
|
package eu.crushedpixel.replaymod.mixin;
|
||||||
|
|
||||||
|
import eu.crushedpixel.replaymod.renderer.SpectatorRenderer;
|
||||||
|
import eu.crushedpixel.replaymod.replay.ReplayHandler;
|
||||||
|
import eu.crushedpixel.replaymod.settings.RenderOptions;
|
||||||
|
import eu.crushedpixel.replaymod.video.EntityRendererHandler;
|
||||||
|
import eu.crushedpixel.replaymod.video.capturer.CubicOpenGlFrameCapturer;
|
||||||
|
import eu.crushedpixel.replaymod.video.capturer.StereoscopicOpenGlFrameCapturer;
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.client.renderer.EntityRenderer;
|
||||||
|
import net.minecraft.client.renderer.GlStateManager;
|
||||||
|
import net.minecraft.client.renderer.RenderGlobal;
|
||||||
|
import net.minecraft.client.renderer.culling.Frustum;
|
||||||
|
import net.minecraft.client.settings.GameSettings;
|
||||||
|
import net.minecraft.entity.Entity;
|
||||||
|
import net.minecraft.entity.player.EntityPlayer;
|
||||||
|
import net.minecraft.util.MovingObjectPosition;
|
||||||
|
import org.lwjgl.opengl.GL11;
|
||||||
|
import org.lwjgl.util.glu.Project;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
|
||||||
|
@Mixin(EntityRenderer.class)
|
||||||
|
public abstract class MixinEntityRenderer implements EntityRendererHandler.IEntityRenderer, EntityRendererHandler.GluPerspective {
|
||||||
|
private EntityRendererHandler handler;
|
||||||
|
private SpectatorRenderer spectatorRenderer;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setHandler(EntityRendererHandler handler) {
|
||||||
|
this.handler = handler;
|
||||||
|
if (spectatorRenderer != null) {
|
||||||
|
spectatorRenderer.cleanup();
|
||||||
|
spectatorRenderer = null;
|
||||||
|
}
|
||||||
|
if (handler != null) {
|
||||||
|
spectatorRenderer = new SpectatorRenderer();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EntityRendererHandler getHandler() {
|
||||||
|
return handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Inject(method = "setupFog", at = @At("HEAD"), cancellable = true)
|
||||||
|
private void onSetupFog(int fogDistanceFlag, float partialTicks, CallbackInfo ci) {
|
||||||
|
if (handler == null) return;
|
||||||
|
if (!handler.getOptions().isDefaultSky()) {
|
||||||
|
ci.cancel();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Redirect(method = "renderWorldPass", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/culling/Frustum;setPosition(DDD)V"))
|
||||||
|
public void createNoCullingFrustum(Frustum frustum, double x, double y, double z) {
|
||||||
|
if (handler != null) {
|
||||||
|
frustum.clippingHelper = new EntityRendererHandler.NoCullingClippingHelper();
|
||||||
|
}
|
||||||
|
frustum.setPosition(x, y, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Inject(method = "orientCamera", at = @At("HEAD"))
|
||||||
|
private void resetRotationIfNeeded(float partialTicks, CallbackInfo ci) {
|
||||||
|
if (handler != null) {
|
||||||
|
Entity entity = Minecraft.getMinecraft().getRenderViewEntity();
|
||||||
|
RenderOptions options = handler.getOptions();
|
||||||
|
if (options.getIgnoreCameraRotation()[0]) {
|
||||||
|
entity.prevRotationYaw = entity.rotationYaw = 0;
|
||||||
|
}
|
||||||
|
if (options.getIgnoreCameraRotation()[1]) {
|
||||||
|
entity.prevRotationPitch = entity.rotationPitch = 0;
|
||||||
|
}
|
||||||
|
if (options.getIgnoreCameraRotation()[2]) {
|
||||||
|
ReplayHandler.setCameraTilt(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private float orgYaw;
|
||||||
|
private float orgPitch;
|
||||||
|
private float orgPrevYaw;
|
||||||
|
private float orgPrevPitch;
|
||||||
|
private float orgRoll;
|
||||||
|
|
||||||
|
@Inject(method = "setupCameraTransform", at = @At("HEAD"))
|
||||||
|
private void beforeSetupCameraTransform(float partialTicks, int renderPass, CallbackInfo ci) {
|
||||||
|
if (handler != null) {
|
||||||
|
Entity entity = Minecraft.getMinecraft().getRenderViewEntity();
|
||||||
|
orgYaw = entity.rotationYaw;
|
||||||
|
orgPitch = entity.rotationPitch;
|
||||||
|
orgPrevYaw = entity.prevRotationYaw;
|
||||||
|
orgPrevPitch = entity.prevRotationPitch;
|
||||||
|
orgRoll = ReplayHandler.getCameraTilt();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Inject(method = "setupCameraTransform", at = @At("RETURN"))
|
||||||
|
private void afterSetupCameraTransform(float partialTicks, int renderPass, CallbackInfo ci) {
|
||||||
|
if (handler != null) {
|
||||||
|
Entity entity = Minecraft.getMinecraft().getRenderViewEntity();
|
||||||
|
entity.rotationYaw = orgYaw;
|
||||||
|
entity.rotationPitch = orgPitch;
|
||||||
|
entity.prevRotationYaw = orgPrevYaw;
|
||||||
|
entity.prevRotationPitch = orgPrevPitch;
|
||||||
|
ReplayHandler.setCameraTilt(orgRoll);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Inject(method = "renderHand", at = @At("HEAD"), cancellable = true)
|
||||||
|
private void renderSpectatorHand(float partialTicks, int renderPass, CallbackInfo ci) {
|
||||||
|
if (handler != null) {
|
||||||
|
if (handler.data instanceof CubicOpenGlFrameCapturer.Data) {
|
||||||
|
return; // No spectator hands during 360° view, we wouldn't even know where to put it
|
||||||
|
}
|
||||||
|
Entity currentEntity = ReplayHandler.getCurrentEntity();
|
||||||
|
if (!ReplayHandler.isCamera() && currentEntity instanceof EntityPlayer) {
|
||||||
|
renderPass = handler.data == StereoscopicOpenGlFrameCapturer.Data.LEFT_EYE ? 1 : 0;
|
||||||
|
spectatorRenderer.renderSpectatorHand((EntityPlayer) currentEntity, partialTicks, renderPass);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Redirect(method = "renderWorldPass", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/RenderGlobal;drawSelectionBox(Lnet/minecraft/entity/player/EntityPlayer;Lnet/minecraft/util/MovingObjectPosition;IF)V"))
|
||||||
|
private void drawSelectionBox(RenderGlobal instance, EntityPlayer player, MovingObjectPosition mop, int alwaysZero, float partialTicks) {
|
||||||
|
if (handler == null) {
|
||||||
|
instance.drawSelectionBox(player, mop, alwaysZero, partialTicks);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private int orgRenderDistanceChunks;
|
||||||
|
|
||||||
|
@Inject(method = "renderWorldPass", at = @At(value = "JUMP", ordinal = 0))
|
||||||
|
private void beforeRenderSky(CallbackInfo ci) {
|
||||||
|
if (handler != null && !handler.getOptions().isDefaultSky()) {
|
||||||
|
GameSettings settings = Minecraft.getMinecraft().gameSettings;
|
||||||
|
orgRenderDistanceChunks = settings.renderDistanceChunks;
|
||||||
|
settings.renderDistanceChunks = 5; // Set render distance to 5 so we're always rendering sky when chroma keying
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Redirect(method = "renderWorldPass", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/RenderGlobal;renderSky(FI)V"))
|
||||||
|
private void renderSky(RenderGlobal instance, float partialTicks, int renderPass) {
|
||||||
|
if (handler != null && !handler.getOptions().isDefaultSky()) {
|
||||||
|
Minecraft.getMinecraft().gameSettings.renderDistanceChunks = orgRenderDistanceChunks;
|
||||||
|
int c = handler.getOptions().getSkyColor();
|
||||||
|
GlStateManager.clearColor((c >> 16 & 0xff) / (float) 0xff, (c >> 8 & 0xff) / (float) 0xff, (c & 0xff) / (float) 0xff, 1);
|
||||||
|
GlStateManager.clear(GL11.GL_COLOR_BUFFER_BIT);
|
||||||
|
} else {
|
||||||
|
instance.renderSky(partialTicks, renderPass);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Cubic Renderer
|
||||||
|
*/
|
||||||
|
|
||||||
|
@Inject(method = "setupCameraTransform", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/GlStateManager;loadIdentity()V", shift = At.Shift.AFTER, ordinal = 0))
|
||||||
|
private void setupStereoscopicProjection(float partialTicks, int renderPass, CallbackInfo ci) {
|
||||||
|
if (getHandler() != null) {
|
||||||
|
if (getHandler().data == StereoscopicOpenGlFrameCapturer.Data.LEFT_EYE) {
|
||||||
|
GlStateManager.translate(0.07, 0, 0);
|
||||||
|
} else if (getHandler().data == StereoscopicOpenGlFrameCapturer.Data.RIGHT_EYE) {
|
||||||
|
GlStateManager.translate(-0.07, 0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Inject(method = "setupCameraTransform", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/GlStateManager;loadIdentity()V", shift = At.Shift.AFTER, ordinal = 1))
|
||||||
|
private void setupStereoscopicModelView(float partialTicks, int renderPass, CallbackInfo ci) {
|
||||||
|
if (getHandler() != null) {
|
||||||
|
if (getHandler().data == StereoscopicOpenGlFrameCapturer.Data.LEFT_EYE) {
|
||||||
|
GlStateManager.translate(0.1, 0, 0);
|
||||||
|
} else if (getHandler().data == StereoscopicOpenGlFrameCapturer.Data.RIGHT_EYE) {
|
||||||
|
GlStateManager.translate(-0.1, 0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Cubic Renderer
|
||||||
|
*/
|
||||||
|
|
||||||
|
@Redirect(method = "setupCameraTransform", at = @At(value = "INVOKE", target = "Lorg/lwjgl/util/glu/Project;gluPerspective(FFFF)V", remap = false))
|
||||||
|
private void gluPerspective$0(float fovY, float aspect, float zNear, float zFar) {
|
||||||
|
gluPerspective(fovY, aspect, zNear, zFar);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Redirect(method = "renderWorldPass", at = @At(value = "INVOKE", target = "Lorg/lwjgl/util/glu/Project;gluPerspective(FFFF)V", remap = false))
|
||||||
|
private void gluPerspective$1(float fovY, float aspect, float zNear, float zFar) {
|
||||||
|
gluPerspective(fovY, aspect, zNear, zFar);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Redirect(method = "renderCloudsCheck", at = @At(value = "INVOKE", target = "Lorg/lwjgl/util/glu/Project;gluPerspective(FFFF)V", remap = false))
|
||||||
|
private void gluPerspective$2(float fovY, float aspect, float zNear, float zFar) {
|
||||||
|
gluPerspective(fovY, aspect, zNear, zFar);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void gluPerspective(float fovY, float aspect, float zNear, float zFar) {
|
||||||
|
if (getHandler() != null && getHandler().data instanceof CubicOpenGlFrameCapturer.Data) {
|
||||||
|
fovY = 90;
|
||||||
|
aspect = 1;
|
||||||
|
}
|
||||||
|
Project.gluPerspective(fovY, aspect, zNear, zFar);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Inject(method = "orientCamera", at = @At("HEAD"))
|
||||||
|
private void setupCubicFrameRotation(float partialTicks, CallbackInfo ci) {
|
||||||
|
if (getHandler() != null && getHandler().data instanceof CubicOpenGlFrameCapturer.Data) {
|
||||||
|
switch ((CubicOpenGlFrameCapturer.Data) getHandler().data) {
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Minecraft goes back a little so we have to invert that
|
||||||
|
GlStateManager.translate(0.0F, 0.0F, 0.1F);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
package eu.crushedpixel.replaymod.mixin;
|
||||||
|
|
||||||
|
import eu.crushedpixel.replaymod.video.EntityRendererHandler;
|
||||||
|
import eu.crushedpixel.replaymod.video.capturer.CubicOpenGlFrameCapturer;
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.client.renderer.entity.RenderManager;
|
||||||
|
import net.minecraft.entity.Entity;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||||
|
|
||||||
|
@Mixin(RenderManager.class)
|
||||||
|
public class MixinRenderManager {
|
||||||
|
@Shadow
|
||||||
|
private float playerViewX;
|
||||||
|
|
||||||
|
@Shadow
|
||||||
|
private float playerViewY;
|
||||||
|
|
||||||
|
@Inject(method = "doRenderEntity", at = @At("HEAD"))
|
||||||
|
private void reorientForCubicRendering(Entity entity, double dx, double dy, double dz, float iDoNotKnow, float partialTicks, boolean iDoNotCare, CallbackInfoReturnable ci) {
|
||||||
|
EntityRendererHandler handler = ((EntityRendererHandler.IEntityRenderer) Minecraft.getMinecraft().entityRenderer).getHandler();
|
||||||
|
if (handler != null && handler.data instanceof CubicOpenGlFrameCapturer.Data) {
|
||||||
|
double pitch = -Math.atan2(dy, Math.sqrt(dx * dx + dz * dz));
|
||||||
|
double yaw = -Math.atan2(dx, dz);
|
||||||
|
playerViewX = (float) Math.toDegrees(pitch);
|
||||||
|
playerViewY = (float) Math.toDegrees(yaw);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,6 +2,7 @@ package eu.crushedpixel.replaymod.renderer;
|
|||||||
|
|
||||||
import eu.crushedpixel.replaymod.replay.ReplayHandler;
|
import eu.crushedpixel.replaymod.replay.ReplayHandler;
|
||||||
import eu.crushedpixel.replaymod.utils.SkinProvider;
|
import eu.crushedpixel.replaymod.utils.SkinProvider;
|
||||||
|
import eu.crushedpixel.replaymod.video.EntityRendererHandler;
|
||||||
import net.minecraft.block.material.Material;
|
import net.minecraft.block.material.Material;
|
||||||
import net.minecraft.block.state.IBlockState;
|
import net.minecraft.block.state.IBlockState;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
@@ -25,7 +26,6 @@ import net.minecraftforge.fml.common.FMLCommonHandler;
|
|||||||
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
||||||
import net.minecraftforge.fml.common.gameevent.TickEvent;
|
import net.minecraftforge.fml.common.gameevent.TickEvent;
|
||||||
import org.lwjgl.opengl.GL11;
|
import org.lwjgl.opengl.GL11;
|
||||||
import org.lwjgl.util.glu.Project;
|
|
||||||
|
|
||||||
public class SpectatorRenderer {
|
public class SpectatorRenderer {
|
||||||
|
|
||||||
@@ -43,10 +43,6 @@ public class SpectatorRenderer {
|
|||||||
return (EntityPlayer)current;
|
return (EntityPlayer)current;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void gluPerspective(float fovY, float aspect, float zNear, float zFar) {
|
|
||||||
Project.gluPerspective(fovY, aspect, zNear, zFar);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void renderSpectatorHand(EntityPlayer entityPlayer, float partialTicks, int renderPass) {
|
public void renderSpectatorHand(EntityPlayer entityPlayer, float partialTicks, int renderPass) {
|
||||||
if(entityPlayer.isInvisible()) return;
|
if(entityPlayer.isInvisible()) return;
|
||||||
|
|
||||||
@@ -65,7 +61,7 @@ public class SpectatorRenderer {
|
|||||||
GlStateManager.translate((float)(-(renderPass * 2 - 1)) * f1, 0.0F, 0.0F);
|
GlStateManager.translate((float)(-(renderPass * 2 - 1)) * f1, 0.0F, 0.0F);
|
||||||
}
|
}
|
||||||
|
|
||||||
gluPerspective(mc.entityRenderer.getFOVModifier(partialTicks, false),
|
((EntityRendererHandler.GluPerspective) mc.entityRenderer).gluPerspective(mc.entityRenderer.getFOVModifier(partialTicks, false),
|
||||||
(float) this.mc.displayWidth / (float) this.mc.displayHeight, 0.05F, mc.entityRenderer.farPlaneDistance * 2.0F);
|
(float) this.mc.displayWidth / (float) this.mc.displayHeight, 0.05F, mc.entityRenderer.farPlaneDistance * 2.0F);
|
||||||
|
|
||||||
GlStateManager.matrixMode(GL11.GL_MODELVIEW);
|
GlStateManager.matrixMode(GL11.GL_MODELVIEW);
|
||||||
|
|||||||
@@ -0,0 +1,89 @@
|
|||||||
|
package eu.crushedpixel.replaymod.video;
|
||||||
|
|
||||||
|
import eu.crushedpixel.replaymod.coremod.asm_Hooks;
|
||||||
|
import eu.crushedpixel.replaymod.settings.RenderOptions;
|
||||||
|
import eu.crushedpixel.replaymod.video.capturer.CaptureData;
|
||||||
|
import eu.crushedpixel.replaymod.video.capturer.WorldRenderer;
|
||||||
|
import lombok.Getter;
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.client.renderer.culling.ClippingHelper;
|
||||||
|
import org.lwjgl.util.ReadableDimension;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import static net.minecraft.client.renderer.GlStateManager.*;
|
||||||
|
|
||||||
|
public class EntityRendererHandler implements WorldRenderer {
|
||||||
|
public final Minecraft mc = Minecraft.getMinecraft();
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
protected final RenderOptions options;
|
||||||
|
|
||||||
|
public CaptureData data;
|
||||||
|
|
||||||
|
public EntityRendererHandler(RenderOptions options) {
|
||||||
|
this.options = options;
|
||||||
|
|
||||||
|
if (options.isHideNameTags()) {
|
||||||
|
asm_Hooks.DO_NOT_RENDER_NAME_TAGS = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
((IEntityRenderer) mc.entityRenderer).setHandler(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void withDisplaySize(int displayWidth, int displayHeight, Runnable runnable) {
|
||||||
|
final int prevWidth = mc.displayWidth;
|
||||||
|
final int prevHeight = mc.displayHeight;
|
||||||
|
mc.displayWidth = displayWidth;
|
||||||
|
mc.displayHeight = displayHeight;
|
||||||
|
|
||||||
|
runnable.run();
|
||||||
|
|
||||||
|
mc.displayWidth = prevWidth;
|
||||||
|
mc.displayHeight = prevHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void renderWorld(ReadableDimension displaySize, final float partialTicks, CaptureData data) {
|
||||||
|
this.data = data;
|
||||||
|
withDisplaySize(displaySize.getWidth(), displaySize.getHeight(), new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
renderWorld(partialTicks, 0);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void renderWorld(float partialTicks, long finishTimeNano) {
|
||||||
|
mc.entityRenderer.updateLightmap(partialTicks);
|
||||||
|
|
||||||
|
enableDepth();
|
||||||
|
enableAlpha();
|
||||||
|
alphaFunc(516, 0.5F);
|
||||||
|
|
||||||
|
mc.entityRenderer.renderWorldPass(2, partialTicks, finishTimeNano);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() throws IOException {
|
||||||
|
((IEntityRenderer) mc.entityRenderer).setHandler(null);
|
||||||
|
|
||||||
|
asm_Hooks.DO_NOT_RENDER_NAME_TAGS = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final class NoCullingClippingHelper extends ClippingHelper {
|
||||||
|
@Override
|
||||||
|
public boolean isBoxInFrustum(double p_78553_1_, double p_78553_3_, double p_78553_5_, double p_78553_7_, double p_78553_9_, double p_78553_11_) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface GluPerspective {
|
||||||
|
void gluPerspective(float fovY, float aspect, float zNear, float zFar);
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface IEntityRenderer {
|
||||||
|
void setHandler(EntityRendererHandler handler);
|
||||||
|
EntityRendererHandler getHandler();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -8,7 +8,7 @@ public class CubicOpenGlFrameCapturer extends OpenGlFrameCapturer<CubicOpenGlFra
|
|||||||
}
|
}
|
||||||
|
|
||||||
private final int frameSize;
|
private final int frameSize;
|
||||||
public CubicOpenGlFrameCapturer(WorldRenderer<Data> worldRenderer, RenderInfo renderInfo, int frameSize) {
|
public CubicOpenGlFrameCapturer(WorldRenderer worldRenderer, RenderInfo renderInfo, int frameSize) {
|
||||||
super(worldRenderer, renderInfo);
|
super(worldRenderer, renderInfo);
|
||||||
this.frameSize = frameSize;
|
this.frameSize = frameSize;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,8 +7,7 @@ public class CubicPboOpenGlFrameCapturer extends
|
|||||||
MultiFramePboOpenGlFrameCapturer<CubicOpenGlFrame, CubicOpenGlFrameCapturer.Data> {
|
MultiFramePboOpenGlFrameCapturer<CubicOpenGlFrame, CubicOpenGlFrameCapturer.Data> {
|
||||||
|
|
||||||
private final int frameSize;
|
private final int frameSize;
|
||||||
public CubicPboOpenGlFrameCapturer(WorldRenderer<CubicOpenGlFrameCapturer.Data> worldRenderer,
|
public CubicPboOpenGlFrameCapturer(WorldRenderer worldRenderer, RenderInfo renderInfo, int frameSize) {
|
||||||
RenderInfo renderInfo, int frameSize) {
|
|
||||||
super(worldRenderer, renderInfo, CubicOpenGlFrameCapturer.Data.class, frameSize * frameSize);
|
super(worldRenderer, renderInfo, CubicOpenGlFrameCapturer.Data.class, frameSize * frameSize);
|
||||||
this.frameSize = frameSize;
|
this.frameSize = frameSize;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ public abstract class MultiFramePboOpenGlFrameCapturer<F extends Frame, D extend
|
|||||||
private final D[] data;
|
private final D[] data;
|
||||||
private PixelBufferObject pbo, otherPBO;
|
private PixelBufferObject pbo, otherPBO;
|
||||||
|
|
||||||
public MultiFramePboOpenGlFrameCapturer(WorldRenderer<D> worldRenderer, RenderInfo renderInfo, Class<D> type, int framePixels) {
|
public MultiFramePboOpenGlFrameCapturer(WorldRenderer worldRenderer, RenderInfo renderInfo, Class<D> type, int framePixels) {
|
||||||
super(worldRenderer, renderInfo);
|
super(worldRenderer, renderInfo);
|
||||||
|
|
||||||
data = type.getEnumConstants();
|
data = type.getEnumConstants();
|
||||||
@@ -97,6 +97,7 @@ public abstract class MultiFramePboOpenGlFrameCapturer<F extends Frame, D extend
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void close() throws IOException {
|
public void close() throws IOException {
|
||||||
|
super.close();
|
||||||
pbo.delete();
|
pbo.delete();
|
||||||
otherPBO.delete();
|
otherPBO.delete();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,12 +19,12 @@ import static org.lwjgl.opengl.GL11.GL_COLOR_BUFFER_BIT;
|
|||||||
import static org.lwjgl.opengl.GL11.GL_DEPTH_BUFFER_BIT;
|
import static org.lwjgl.opengl.GL11.GL_DEPTH_BUFFER_BIT;
|
||||||
|
|
||||||
public abstract class OpenGlFrameCapturer<F extends Frame, D extends CaptureData> implements FrameCapturer<F> {
|
public abstract class OpenGlFrameCapturer<F extends Frame, D extends CaptureData> implements FrameCapturer<F> {
|
||||||
protected final WorldRenderer<D> worldRenderer;
|
protected final WorldRenderer worldRenderer;
|
||||||
protected final RenderInfo renderInfo;
|
protected final RenderInfo renderInfo;
|
||||||
protected int framesDone;
|
protected int framesDone;
|
||||||
private Framebuffer frameBuffer;
|
private Framebuffer frameBuffer;
|
||||||
|
|
||||||
public OpenGlFrameCapturer(WorldRenderer<D> worldRenderer, RenderInfo renderInfo) {
|
public OpenGlFrameCapturer(WorldRenderer worldRenderer, RenderInfo renderInfo) {
|
||||||
this.worldRenderer = worldRenderer;
|
this.worldRenderer = worldRenderer;
|
||||||
this.renderInfo = renderInfo;
|
this.renderInfo = renderInfo;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import eu.crushedpixel.replaymod.video.frame.OpenGlFrame;
|
|||||||
|
|
||||||
public class SimpleOpenGlFrameCapturer extends OpenGlFrameCapturer<OpenGlFrame, CaptureData> {
|
public class SimpleOpenGlFrameCapturer extends OpenGlFrameCapturer<OpenGlFrame, CaptureData> {
|
||||||
|
|
||||||
public SimpleOpenGlFrameCapturer(WorldRenderer<CaptureData> worldRenderer, RenderInfo renderInfo) {
|
public SimpleOpenGlFrameCapturer(WorldRenderer worldRenderer, RenderInfo renderInfo) {
|
||||||
super(worldRenderer, renderInfo);
|
super(worldRenderer, renderInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ public class SimplePboOpenGlFrameCapturer extends OpenGlFrameCapturer<OpenGlFram
|
|||||||
private final int bufferSize;
|
private final int bufferSize;
|
||||||
private PixelBufferObject pbo, otherPBO;
|
private PixelBufferObject pbo, otherPBO;
|
||||||
|
|
||||||
public SimplePboOpenGlFrameCapturer(WorldRenderer<CaptureData> worldRenderer, RenderInfo renderInfo) {
|
public SimplePboOpenGlFrameCapturer(WorldRenderer worldRenderer, RenderInfo renderInfo) {
|
||||||
super(worldRenderer, renderInfo);
|
super(worldRenderer, renderInfo);
|
||||||
|
|
||||||
ReadableDimension size = renderInfo.getFrameSize();
|
ReadableDimension size = renderInfo.getFrameSize();
|
||||||
@@ -81,6 +81,7 @@ public class SimplePboOpenGlFrameCapturer extends OpenGlFrameCapturer<OpenGlFram
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void close() throws IOException {
|
public void close() throws IOException {
|
||||||
|
super.close();
|
||||||
pbo.delete();
|
pbo.delete();
|
||||||
otherPBO.delete();
|
otherPBO.delete();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ public class StereoscopicOpenGlFrameCapturer
|
|||||||
LEFT_EYE, RIGHT_EYE
|
LEFT_EYE, RIGHT_EYE
|
||||||
}
|
}
|
||||||
|
|
||||||
public StereoscopicOpenGlFrameCapturer(WorldRenderer<Data> worldRenderer, RenderInfo renderInfo) {
|
public StereoscopicOpenGlFrameCapturer(WorldRenderer worldRenderer, RenderInfo renderInfo) {
|
||||||
super(worldRenderer, renderInfo);
|
super(worldRenderer, renderInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,8 +6,7 @@ import eu.crushedpixel.replaymod.video.frame.StereoscopicOpenGlFrame;
|
|||||||
public class StereoscopicPboOpenGlFrameCapturer
|
public class StereoscopicPboOpenGlFrameCapturer
|
||||||
extends MultiFramePboOpenGlFrameCapturer<StereoscopicOpenGlFrame, StereoscopicOpenGlFrameCapturer.Data> {
|
extends MultiFramePboOpenGlFrameCapturer<StereoscopicOpenGlFrame, StereoscopicOpenGlFrameCapturer.Data> {
|
||||||
|
|
||||||
public StereoscopicPboOpenGlFrameCapturer(WorldRenderer<StereoscopicOpenGlFrameCapturer.Data> worldRenderer,
|
public StereoscopicPboOpenGlFrameCapturer(WorldRenderer worldRenderer, RenderInfo renderInfo) {
|
||||||
RenderInfo renderInfo) {
|
|
||||||
super(worldRenderer, renderInfo, StereoscopicOpenGlFrameCapturer.Data.class,
|
super(worldRenderer, renderInfo, StereoscopicOpenGlFrameCapturer.Data.class,
|
||||||
renderInfo.getFrameSize().getWidth() / 2 * renderInfo.getFrameSize().getHeight());
|
renderInfo.getFrameSize().getWidth() / 2 * renderInfo.getFrameSize().getHeight());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,6 @@ import org.lwjgl.util.ReadableDimension;
|
|||||||
|
|
||||||
import java.io.Closeable;
|
import java.io.Closeable;
|
||||||
|
|
||||||
public interface WorldRenderer<D extends CaptureData> extends Closeable {
|
public interface WorldRenderer extends Closeable {
|
||||||
void renderWorld(ReadableDimension displaySize, float partialTicks, D data);
|
void renderWorld(ReadableDimension displaySize, float partialTicks, CaptureData data);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,117 +0,0 @@
|
|||||||
package eu.crushedpixel.replaymod.video.entity;
|
|
||||||
|
|
||||||
import eu.crushedpixel.replaymod.settings.RenderOptions;
|
|
||||||
import eu.crushedpixel.replaymod.video.capturer.CubicOpenGlFrameCapturer;
|
|
||||||
import net.minecraft.client.particle.EntityFX;
|
|
||||||
import net.minecraft.client.renderer.GlStateManager;
|
|
||||||
import net.minecraft.client.renderer.WorldRenderer;
|
|
||||||
import net.minecraft.client.renderer.entity.RenderManager;
|
|
||||||
import net.minecraft.entity.Entity;
|
|
||||||
import net.minecraft.util.ResourceLocation;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.lang.reflect.Field;
|
|
||||||
|
|
||||||
public class CubicEntityRenderer extends CustomEntityRenderer<CubicOpenGlFrameCapturer.Data> {
|
|
||||||
|
|
||||||
public CubicEntityRenderer(RenderOptions options) {
|
|
||||||
super(options);
|
|
||||||
|
|
||||||
try {
|
|
||||||
Field hookField = RenderManager.class.getField("hook");
|
|
||||||
hookField.set(mc.getRenderManager(), this);
|
|
||||||
} catch (NoSuchFieldException e) {
|
|
||||||
throw new Error(e);
|
|
||||||
} catch (IllegalAccessException e) {
|
|
||||||
throw new Error(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void close() throws IOException{
|
|
||||||
super.close();
|
|
||||||
try {
|
|
||||||
Field hookField = RenderManager.class.getField("hook");
|
|
||||||
hookField.set(mc.getRenderManager(), null);
|
|
||||||
} catch (NoSuchFieldException e) {
|
|
||||||
throw new Error(e);
|
|
||||||
} catch (IllegalAccessException e) {
|
|
||||||
throw new Error(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void gluPerspective(float fovY, float aspect, float zNear, float zFar) {
|
|
||||||
super.gluPerspective(90, 1, zNear, zFar);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void loadShader(ResourceLocation resourceLocation) {
|
|
||||||
if (proxied.theShaderGroup != null) {
|
|
||||||
proxied.theShaderGroup.deleteShaderGroup();
|
|
||||||
proxied.theShaderGroup = null;
|
|
||||||
}
|
|
||||||
proxied.useShader = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void orientCamera(float partialTicks) {
|
|
||||||
// Rotate
|
|
||||||
switch (data) {
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Minecraft goes back a little so we have to invert that
|
|
||||||
GlStateManager.translate(0.0F, 0.0F, 0.1F);
|
|
||||||
super.orientCamera(partialTicks);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unused") // Called by ASM
|
|
||||||
public void beforeEntityRender(double dx, double dy, double dz) {
|
|
||||||
double pitch = -Math.atan2(dy, Math.sqrt(dx * dx + dz * dz));
|
|
||||||
double yaw = -Math.atan2(dx, dz);
|
|
||||||
mc.getRenderManager().playerViewX = (float) Math.toDegrees(pitch);
|
|
||||||
mc.getRenderManager().playerViewY = (float) Math.toDegrees(yaw);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,465 +0,0 @@
|
|||||||
package eu.crushedpixel.replaymod.video.entity;
|
|
||||||
|
|
||||||
import eu.crushedpixel.replaymod.coremod.asm_Hooks;
|
|
||||||
import eu.crushedpixel.replaymod.renderer.SpectatorRenderer;
|
|
||||||
import eu.crushedpixel.replaymod.replay.ReplayHandler;
|
|
||||||
import eu.crushedpixel.replaymod.settings.RenderOptions;
|
|
||||||
import eu.crushedpixel.replaymod.video.capturer.CaptureData;
|
|
||||||
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;
|
|
||||||
import net.minecraft.util.AxisAlignedBB;
|
|
||||||
import net.minecraft.util.EnumWorldBlockLayer;
|
|
||||||
import net.minecraft.util.MathHelper;
|
|
||||||
import net.minecraft.util.ResourceLocation;
|
|
||||||
import org.lwjgl.util.ReadableDimension;
|
|
||||||
import org.lwjgl.util.glu.Project;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.lang.reflect.Field;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import static net.minecraft.client.renderer.GlStateManager.*;
|
|
||||||
import static org.lwjgl.opengl.GL11.*;
|
|
||||||
|
|
||||||
public class CustomEntityRenderer<D extends CaptureData> implements eu.crushedpixel.replaymod.video.capturer.WorldRenderer<D> {
|
|
||||||
public final Minecraft mc = Minecraft.getMinecraft();
|
|
||||||
public final EntityRenderer proxied = mc.entityRenderer;
|
|
||||||
protected final SpectatorRenderer spectatorRenderer = new SpectatorRenderer(){
|
|
||||||
@Override
|
|
||||||
protected void gluPerspective(float fovY, float aspect, float zNear, float zFar) {
|
|
||||||
CustomEntityRenderer.this.gluPerspective(fovY, aspect, zNear, zFar);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
public GluPerspectiveHook gluPerspectiveHook;
|
|
||||||
public LoadShaderHook loadShaderHook;
|
|
||||||
protected int frameCount;
|
|
||||||
|
|
||||||
protected D data;
|
|
||||||
|
|
||||||
protected final RenderOptions options;
|
|
||||||
|
|
||||||
|
|
||||||
public CustomEntityRenderer(RenderOptions options) {
|
|
||||||
this.options = options;
|
|
||||||
|
|
||||||
// Install entity renderer hooks
|
|
||||||
try {
|
|
||||||
Field hookField = EntityRenderer.class.getField("hook");
|
|
||||||
hookField.set(proxied, this);
|
|
||||||
} catch (NoSuchFieldException e) {
|
|
||||||
throw new Error(e);
|
|
||||||
} catch (IllegalAccessException e) {
|
|
||||||
throw new Error(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (options.isHideNameTags()) {
|
|
||||||
asm_Hooks.DO_NOT_RENDER_NAME_TAGS = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unused") // Method called by ASM hook
|
|
||||||
public void loadShader(ResourceLocation resourceLocation) {
|
|
||||||
if (loadShaderHook != null) {
|
|
||||||
loadShaderHook.loadShader(resourceLocation);
|
|
||||||
} else {
|
|
||||||
original_loadShader(resourceLocation);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
|
||||||
protected final void original_loadShader(ResourceLocation resourceLocation) {
|
|
||||||
// Method body generated by ASM
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void gluPerspective(float fovY, float aspect, float zNear, float zFar) {
|
|
||||||
if (gluPerspectiveHook == null) {
|
|
||||||
Project.gluPerspective(fovY, aspect, zNear, zFar);
|
|
||||||
} else {
|
|
||||||
gluPerspectiveHook.gluPerspective(fovY, aspect, zNear, zFar);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void withDisplaySize(int displayWidth, int displayHeight, Runnable runnable) {
|
|
||||||
final int prevWidth = mc.displayWidth;
|
|
||||||
final int prevHeight = mc.displayHeight;
|
|
||||||
mc.displayWidth = displayWidth;
|
|
||||||
mc.displayHeight = displayHeight;
|
|
||||||
|
|
||||||
runnable.run();
|
|
||||||
|
|
||||||
mc.displayWidth = prevWidth;
|
|
||||||
mc.displayHeight = prevHeight;
|
|
||||||
}
|
|
||||||
|
|
||||||
public 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;
|
|
||||||
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 || !options.isDefaultSky() ) {
|
|
||||||
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);
|
|
||||||
if (options.isDefaultSky()) {
|
|
||||||
renderglobal.renderSky(partialTicks, renderPass);
|
|
||||||
} else {
|
|
||||||
int c = options.getSkyColor();
|
|
||||||
clearColor((c >> 16 & 0xff) / (float) 0xff, (c >> 8 & 0xff) / (float) 0xff, (c & 0xff) / (float) 0xff, 1);
|
|
||||||
clear(GL_COLOR_BUFFER_BIT);
|
|
||||||
}
|
|
||||||
matrixMode(GL_PROJECTION);
|
|
||||||
loadIdentity();
|
|
||||||
gluPerspective(proxied.getFOVModifier(partialTicks, true), (float) mc.displayWidth / mc.displayHeight, 0.05F, proxied.farPlaneDistance * MathHelper.SQRT_2);
|
|
||||||
matrixMode(GL_MODELVIEW);
|
|
||||||
}
|
|
||||||
|
|
||||||
setupFog(0, partialTicks);
|
|
||||||
shadeModel(GL_SMOOTH);
|
|
||||||
|
|
||||||
if (entity.posY + entity.getEyeHeight() < 128) {
|
|
||||||
renderCloudsCheck(renderglobal, partialTicks, renderPass);
|
|
||||||
}
|
|
||||||
|
|
||||||
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();
|
|
||||||
|
|
||||||
renderParticles(entity, partialTicks);
|
|
||||||
|
|
||||||
depthMask(false);
|
|
||||||
enableCull();
|
|
||||||
proxied.renderRainSnow(partialTicks);
|
|
||||||
depthMask(true);
|
|
||||||
renderglobal.renderWorldBorder(entity, partialTicks);
|
|
||||||
disableBlend();
|
|
||||||
enableCull();
|
|
||||||
tryBlendFuncSeparate(770, 771, 1, 0);
|
|
||||||
alphaFunc(516, 0.1F);
|
|
||||||
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);
|
|
||||||
|
|
||||||
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<EntityFX> list = (List<EntityFX>) 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();
|
|
||||||
|
|
||||||
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));
|
|
||||||
|
|
||||||
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<EntityFX> list = (List<EntityFX>) 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) {
|
|
||||||
spectatorRenderer.renderSpectatorHand((EntityPlayer) currentEntity, partialTicks, renderPass);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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();
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
entity.rotationYaw = orgYaw;
|
|
||||||
entity.rotationPitch = orgPitch;
|
|
||||||
entity.prevRotationYaw = orgPrevYaw;
|
|
||||||
entity.prevRotationPitch = orgPrevPitch;
|
|
||||||
ReplayHandler.setCameraTilt(orgRoll);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void setupFog(int fogDistanceFlag, float partialTicks) {
|
|
||||||
if (options.isDefaultSky()) {
|
|
||||||
proxied.setupFog(fogDistanceFlag, partialTicks);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void orientCamera(float partialTicks) {
|
|
||||||
Entity entity = mc.getRenderViewEntity();
|
|
||||||
if (options.getIgnoreCameraRotation()[0]) {
|
|
||||||
entity.prevRotationYaw = entity.rotationYaw = 0;
|
|
||||||
}
|
|
||||||
if (options.getIgnoreCameraRotation()[1]) {
|
|
||||||
entity.prevRotationPitch = entity.rotationPitch = 0;
|
|
||||||
}
|
|
||||||
if (options.getIgnoreCameraRotation()[2]) {
|
|
||||||
ReplayHandler.setCameraTilt(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
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();
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void close() throws IOException {
|
|
||||||
try {
|
|
||||||
Field hookField = EntityRenderer.class.getField("hook");
|
|
||||||
hookField.set(proxied, null);
|
|
||||||
} catch (NoSuchFieldException e) {
|
|
||||||
throw new Error(e);
|
|
||||||
} catch (IllegalAccessException e) {
|
|
||||||
throw new Error(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
asm_Hooks.DO_NOT_RENDER_NAME_TAGS = false;
|
|
||||||
|
|
||||||
spectatorRenderer.cleanup();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void renderWorld(ReadableDimension displaySize, final float partialTicks, D data) {
|
|
||||||
this.data = data;
|
|
||||||
withDisplaySize(displaySize.getWidth(), displaySize.getHeight(), new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
renderWorld(partialTicks, 0);
|
|
||||||
if (OpenGlHelper.shadersSupported) {
|
|
||||||
if (proxied.theShaderGroup != null && proxied.useShader) {
|
|
||||||
matrixMode(GL_TEXTURE);
|
|
||||||
|
|
||||||
pushMatrix();
|
|
||||||
loadIdentity();
|
|
||||||
proxied.theShaderGroup.loadShaderGroup(partialTicks);
|
|
||||||
popMatrix();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
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_) {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public interface GluPerspectiveHook {
|
|
||||||
void gluPerspective(float fovY, float aspect, float zNear, float zFar);
|
|
||||||
}
|
|
||||||
|
|
||||||
public interface LoadShaderHook {
|
|
||||||
void loadShader(ResourceLocation resourceLocation);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,54 +0,0 @@
|
|||||||
package eu.crushedpixel.replaymod.video.entity;
|
|
||||||
|
|
||||||
import eu.crushedpixel.replaymod.settings.RenderOptions;
|
|
||||||
import eu.crushedpixel.replaymod.video.capturer.StereoscopicOpenGlFrameCapturer;
|
|
||||||
import net.minecraft.client.renderer.GlStateManager;
|
|
||||||
import net.minecraft.util.MathHelper;
|
|
||||||
import net.minecraft.util.ResourceLocation;
|
|
||||||
|
|
||||||
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<StereoscopicOpenGlFrameCapturer.Data> {
|
|
||||||
|
|
||||||
public StereoscopicEntityRenderer(RenderOptions options) {
|
|
||||||
super(options);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void loadShader(ResourceLocation resourceLocation) {
|
|
||||||
if (proxied.theShaderGroup != null) {
|
|
||||||
proxied.theShaderGroup.deleteShaderGroup();
|
|
||||||
proxied.theShaderGroup = null;
|
|
||||||
}
|
|
||||||
proxied.useShader = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void translateStereoscopic() {
|
|
||||||
GlStateManager.translate(data == StereoscopicOpenGlFrameCapturer.Data.LEFT_EYE ? 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void renderSpectatorHand(float partialTicks, int renderPass) {
|
|
||||||
super.renderSpectatorHand(partialTicks, data == StereoscopicOpenGlFrameCapturer.Data.LEFT_EYE ? 1 : 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -2,10 +2,8 @@ package eu.crushedpixel.replaymod.video.rendering;
|
|||||||
|
|
||||||
import eu.crushedpixel.replaymod.opengl.PixelBufferObject;
|
import eu.crushedpixel.replaymod.opengl.PixelBufferObject;
|
||||||
import eu.crushedpixel.replaymod.settings.RenderOptions;
|
import eu.crushedpixel.replaymod.settings.RenderOptions;
|
||||||
|
import eu.crushedpixel.replaymod.video.EntityRendererHandler;
|
||||||
import eu.crushedpixel.replaymod.video.capturer.*;
|
import eu.crushedpixel.replaymod.video.capturer.*;
|
||||||
import eu.crushedpixel.replaymod.video.entity.CubicEntityRenderer;
|
|
||||||
import eu.crushedpixel.replaymod.video.entity.CustomEntityRenderer;
|
|
||||||
import eu.crushedpixel.replaymod.video.entity.StereoscopicEntityRenderer;
|
|
||||||
import eu.crushedpixel.replaymod.video.frame.CubicOpenGlFrame;
|
import eu.crushedpixel.replaymod.video.frame.CubicOpenGlFrame;
|
||||||
import eu.crushedpixel.replaymod.video.frame.OpenGlFrame;
|
import eu.crushedpixel.replaymod.video.frame.OpenGlFrame;
|
||||||
import eu.crushedpixel.replaymod.video.frame.RGBFrame;
|
import eu.crushedpixel.replaymod.video.frame.RGBFrame;
|
||||||
@@ -40,9 +38,9 @@ public class Pipelines {
|
|||||||
RenderOptions options = renderInfo.getRenderOptions();
|
RenderOptions options = renderInfo.getRenderOptions();
|
||||||
FrameCapturer<OpenGlFrame> capturer;
|
FrameCapturer<OpenGlFrame> capturer;
|
||||||
if (PixelBufferObject.SUPPORTED) {
|
if (PixelBufferObject.SUPPORTED) {
|
||||||
capturer = new SimplePboOpenGlFrameCapturer(new CustomEntityRenderer<CaptureData>(options), renderInfo);
|
capturer = new SimplePboOpenGlFrameCapturer(new EntityRendererHandler(options), renderInfo);
|
||||||
} else {
|
} else {
|
||||||
capturer = new SimpleOpenGlFrameCapturer(new CustomEntityRenderer<CaptureData>(options), renderInfo);
|
capturer = new SimpleOpenGlFrameCapturer(new EntityRendererHandler(options), renderInfo);
|
||||||
}
|
}
|
||||||
return new Pipeline<OpenGlFrame, RGBFrame>(capturer, new OpenGlToRGBProcessor(), consumer);
|
return new Pipeline<OpenGlFrame, RGBFrame>(capturer, new OpenGlToRGBProcessor(), consumer);
|
||||||
}
|
}
|
||||||
@@ -51,9 +49,9 @@ public class Pipelines {
|
|||||||
RenderOptions options = renderInfo.getRenderOptions();
|
RenderOptions options = renderInfo.getRenderOptions();
|
||||||
FrameCapturer<StereoscopicOpenGlFrame> capturer;
|
FrameCapturer<StereoscopicOpenGlFrame> capturer;
|
||||||
if (PixelBufferObject.SUPPORTED) {
|
if (PixelBufferObject.SUPPORTED) {
|
||||||
capturer = new StereoscopicPboOpenGlFrameCapturer(new StereoscopicEntityRenderer(options), renderInfo);
|
capturer = new StereoscopicPboOpenGlFrameCapturer(new EntityRendererHandler(options), renderInfo);
|
||||||
} else {
|
} else {
|
||||||
capturer = new StereoscopicOpenGlFrameCapturer(new StereoscopicEntityRenderer(options), renderInfo);
|
capturer = new StereoscopicOpenGlFrameCapturer(new EntityRendererHandler(options), renderInfo);
|
||||||
}
|
}
|
||||||
return new Pipeline<StereoscopicOpenGlFrame, RGBFrame>(capturer, new StereoscopicToRGBProcessor(), consumer);
|
return new Pipeline<StereoscopicOpenGlFrame, RGBFrame>(capturer, new StereoscopicToRGBProcessor(), consumer);
|
||||||
}
|
}
|
||||||
@@ -62,9 +60,9 @@ public class Pipelines {
|
|||||||
RenderOptions options = renderInfo.getRenderOptions();
|
RenderOptions options = renderInfo.getRenderOptions();
|
||||||
FrameCapturer<CubicOpenGlFrame> capturer;
|
FrameCapturer<CubicOpenGlFrame> capturer;
|
||||||
if (PixelBufferObject.SUPPORTED) {
|
if (PixelBufferObject.SUPPORTED) {
|
||||||
capturer = new CubicPboOpenGlFrameCapturer(new CubicEntityRenderer(options), renderInfo, options.getWidth() / 4);
|
capturer = new CubicPboOpenGlFrameCapturer(new EntityRendererHandler(options), renderInfo, options.getWidth() / 4);
|
||||||
} else {
|
} else {
|
||||||
capturer = new CubicOpenGlFrameCapturer(new CubicEntityRenderer(options), renderInfo, options.getWidth() / 4);
|
capturer = new CubicOpenGlFrameCapturer(new EntityRendererHandler(options), renderInfo, options.getWidth() / 4);
|
||||||
}
|
}
|
||||||
return new Pipeline<CubicOpenGlFrame, RGBFrame>(capturer, new CubicToRGBProcessor(), consumer);
|
return new Pipeline<CubicOpenGlFrame, RGBFrame>(capturer, new CubicToRGBProcessor(), consumer);
|
||||||
}
|
}
|
||||||
@@ -73,9 +71,9 @@ public class Pipelines {
|
|||||||
RenderOptions options = renderInfo.getRenderOptions();
|
RenderOptions options = renderInfo.getRenderOptions();
|
||||||
FrameCapturer<CubicOpenGlFrame> capturer;
|
FrameCapturer<CubicOpenGlFrame> capturer;
|
||||||
if (PixelBufferObject.SUPPORTED) {
|
if (PixelBufferObject.SUPPORTED) {
|
||||||
capturer = new CubicPboOpenGlFrameCapturer(new CubicEntityRenderer(options), renderInfo, options.getWidth() / 4);
|
capturer = new CubicPboOpenGlFrameCapturer(new EntityRendererHandler(options), renderInfo, options.getWidth() / 4);
|
||||||
} else {
|
} else {
|
||||||
capturer = new CubicOpenGlFrameCapturer(new CubicEntityRenderer(options), renderInfo, options.getWidth() / 4);
|
capturer = new CubicOpenGlFrameCapturer(new EntityRendererHandler(options), renderInfo, options.getWidth() / 4);
|
||||||
}
|
}
|
||||||
return new Pipeline<CubicOpenGlFrame, RGBFrame>(capturer, new EquirectangularToRGBProcessor(options.getWidth() / 4), consumer);
|
return new Pipeline<CubicOpenGlFrame, RGBFrame>(capturer, new EquirectangularToRGBProcessor(options.getWidth() / 4), consumer);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,24 +43,8 @@ public net.minecraft.client.resources.ResourcePackRepository field_177321_h # lo
|
|||||||
public net.minecraft.client.resources.ResourcePackRepository field_177322_i # httpRequest
|
public net.minecraft.client.resources.ResourcePackRepository field_177322_i # httpRequest
|
||||||
|
|
||||||
# EntityRenderer
|
# EntityRenderer
|
||||||
public net.minecraft.client.renderer.EntityRenderer field_147711_ac # resourceManager
|
public net.minecraft.client.renderer.EntityRenderer *
|
||||||
public net.minecraft.client.renderer.EntityRenderer field_147707_d # theShaderGroup
|
public net.minecraft.client.renderer.EntityRenderer *()
|
||||||
public net.minecraft.client.renderer.EntityRenderer field_175083_ad # useShader
|
|
||||||
public net.minecraft.client.renderer.EntityRenderer field_78530_s # farPlaneDistance
|
|
||||||
public net.minecraft.client.renderer.EntityRenderer field_78507_R # fovModifierHand
|
|
||||||
public net.minecraft.client.renderer.EntityRenderer field_78506_S # fovModifierHandPrev
|
|
||||||
public net.minecraft.client.renderer.EntityRenderer field_78536_aa # lightmapUpdateNeeded
|
|
||||||
|
|
||||||
public net.minecraft.client.renderer.EntityRenderer func_78467_g(F)V # orientCamera
|
|
||||||
public net.minecraft.client.renderer.EntityRenderer func_78474_d(F)V # renderRainSnow
|
|
||||||
public net.minecraft.client.renderer.EntityRenderer func_78481_a(FZ)F # getFOVModifier
|
|
||||||
public net.minecraft.client.renderer.EntityRenderer func_78468_a(IF)V # setupFog
|
|
||||||
public net.minecraft.client.renderer.EntityRenderer func_78466_h(F)V # updateFogColor
|
|
||||||
public net.minecraft.client.renderer.EntityRenderer func_78472_g(F)V # updateLightmap
|
|
||||||
|
|
||||||
public net.minecraft.client.renderer.EntityRenderer func_78482_e(F)V # hurtCameraEffect
|
|
||||||
public net.minecraft.client.renderer.EntityRenderer func_78475_f(F)V # setupViewBobbing
|
|
||||||
public net.minecraft.client.renderer.EntityRenderer func_78476_b(FI)V # renderHand
|
|
||||||
|
|
||||||
# RenderGlobal
|
# RenderGlobal
|
||||||
public net.minecraft.client.renderer.RenderGlobal field_174995_M # renderDispatcher
|
public net.minecraft.client.renderer.RenderGlobal field_174995_M # renderDispatcher
|
||||||
@@ -102,5 +86,8 @@ public net.minecraft.server.integrated.IntegratedServer field_71348_o # isGamePa
|
|||||||
# GameSettings
|
# GameSettings
|
||||||
public net.minecraft.client.settings.GameSettings field_151446_aD # mapSoundLevels
|
public net.minecraft.client.settings.GameSettings field_151446_aD # mapSoundLevels
|
||||||
|
|
||||||
|
# Frustum
|
||||||
|
public net.minecraft.client.renderer.culling.Frustum field_78552_a # clippingHelper
|
||||||
|
|
||||||
# Example
|
# Example
|
||||||
# public net.minecraft.package.ClassName func_some_id(Ljava/lang/Class;IZS)V # methodName
|
# public net.minecraft.package.ClassName func_some_id(Ljava/lang/Class;IZS)V # methodName
|
||||||
|
|||||||
12
src/main/resources/mixins.replaymod.json
Normal file
12
src/main/resources/mixins.replaymod.json
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"required": true,
|
||||||
|
"package": "eu.crushedpixel.replaymod.mixin",
|
||||||
|
"mixins": [
|
||||||
|
"MixinEffectRenderer",
|
||||||
|
"MixinEntityRenderer",
|
||||||
|
"MixinRenderManager"
|
||||||
|
],
|
||||||
|
"server": [],
|
||||||
|
"client": [],
|
||||||
|
"refmap": "mixins.replaymod.refmap.json"
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user