test worked
This commit is contained in:
@@ -25,7 +25,7 @@ import static com.replaymod.render.ReplayModRender.LOGGER;
|
||||
|
||||
public class RenderSettings {
|
||||
public enum RenderMethod {
|
||||
DEFAULT, STEREOSCOPIC, CUBIC, EQUIRECTANGULAR, ODS, BLEND;
|
||||
DEFAULT, REALLENS, STEREOSCOPIC, CUBIC, EQUIRECTANGULAR, ODS, BLEND;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.replaymod.render.capturer;
|
||||
|
||||
public final class RealLensCameraContext {
|
||||
|
||||
private static final ThreadLocal<RealLensOpenGlFrameCapturer.Data> CURRENT =
|
||||
new ThreadLocal<>();
|
||||
|
||||
private RealLensCameraContext() {}
|
||||
|
||||
public static void set(RealLensOpenGlFrameCapturer.Data data) {
|
||||
CURRENT.set(data);
|
||||
}
|
||||
|
||||
public static RealLensOpenGlFrameCapturer.Data get() {
|
||||
return CURRENT.get();
|
||||
}
|
||||
|
||||
public static void clear() {
|
||||
CURRENT.remove();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
package com.replaymod.render.capturer;
|
||||
|
||||
import com.replaymod.render.frame.OpenGlFrame;
|
||||
import com.replaymod.render.frame.RealLensOpenGlFrame;
|
||||
import com.replaymod.render.rendering.Channel;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
public class RealLensOpenGlFrameCapturer
|
||||
extends OpenGlFrameCapturer<RealLensOpenGlFrame, RealLensOpenGlFrameCapturer.Data> {
|
||||
|
||||
public static class Data implements CaptureData {
|
||||
|
||||
public final float dx, dy, dz;
|
||||
public final float yaw, pitch;
|
||||
|
||||
public Data(float dx, float dy, float dz,
|
||||
float yaw, float pitch) {
|
||||
this.dx = dx;
|
||||
this.dy = dy;
|
||||
this.dz = dz;
|
||||
this.yaw = yaw;
|
||||
this.pitch = pitch;
|
||||
}
|
||||
}
|
||||
|
||||
private static final Data[] CAMERAS = {
|
||||
new Data( 0.25f, 0.00f, 0f, 0f, 0f),
|
||||
new Data( 0.00f, 0.25f, 0f, 0f, 0f),
|
||||
new Data(-0.25f, 0.00f, 0f, 0f, 0f),
|
||||
new Data( 0.00f, -0.25f, 0f, 0f, 0f)
|
||||
};
|
||||
|
||||
public RealLensOpenGlFrameCapturer(
|
||||
WorldRenderer worldRenderer,
|
||||
RenderInfo renderInfo
|
||||
) {
|
||||
super(worldRenderer, renderInfo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<Channel, RealLensOpenGlFrame> process() {
|
||||
|
||||
float partialTicks = renderInfo.updateForNextFrame();
|
||||
int frameId = framesDone++;
|
||||
|
||||
OpenGlFrame[] frames = new OpenGlFrame[CAMERAS.length];
|
||||
|
||||
try {
|
||||
for (int i = 0; i < CAMERAS.length; i++) {
|
||||
|
||||
RealLensCameraContext.set(CAMERAS[i]);
|
||||
|
||||
frames[i] = renderFrame(
|
||||
frameId,
|
||||
partialTicks,
|
||||
CAMERAS[i]
|
||||
);
|
||||
}
|
||||
} finally {
|
||||
RealLensCameraContext.clear();
|
||||
}
|
||||
|
||||
return Collections.singletonMap(
|
||||
Channel.BRGA,
|
||||
new RealLensOpenGlFrame(frames)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package com.replaymod.render.frame;
|
||||
|
||||
import com.replaymod.render.rendering.Frame;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
|
||||
public class RealLensOpenGlFrame implements Frame {
|
||||
|
||||
private final OpenGlFrame[] frames;
|
||||
|
||||
public RealLensOpenGlFrame(OpenGlFrame[] frames) {
|
||||
Validate.notNull(frames, "frames");
|
||||
Validate.isTrue(frames.length > 0, "frames must not be empty");
|
||||
|
||||
int frameId = frames[0].getFrameId();
|
||||
int remaining = frames[0].getByteBuffer().remaining();
|
||||
|
||||
for (OpenGlFrame frame : frames) {
|
||||
Validate.isTrue(
|
||||
frame.getFrameId() == frameId,
|
||||
"Frame ids do not match."
|
||||
);
|
||||
Validate.isTrue(
|
||||
frame.getByteBuffer().remaining() == remaining,
|
||||
"Buffer sizes do not match."
|
||||
);
|
||||
}
|
||||
|
||||
this.frames = frames;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getFrameId() {
|
||||
return frames[0].getFrameId();
|
||||
}
|
||||
|
||||
public OpenGlFrame[] getFrames() {
|
||||
return frames;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
package com.replaymod.render.mixin;
|
||||
|
||||
import com.replaymod.render.capturer.RealLensOpenGlFrameCapturer;
|
||||
import com.replaymod.render.capturer.RealLensCameraContext;
|
||||
import com.replaymod.render.hooks.EntityRendererHandler;
|
||||
import net.minecraft.client.render.GameRenderer;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import net.minecraft.util.math.Matrix4f;
|
||||
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.callback.CallbackInfo;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
//#if MC>=12005
|
||||
//$$ import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
|
||||
//$$ import org.joml.Matrix4f;
|
||||
//#endif
|
||||
|
||||
@Mixin(GameRenderer.class)
|
||||
public abstract class Mixin_RealLens_Camera {
|
||||
|
||||
//#if MC>=12005
|
||||
//#if MC>=12100
|
||||
//$$ @ModifyExpressionValue(method = "renderWorld", at = @At(value = "INVOKE", target = "Lorg/joml/Matrix4f;rotation(Lorg/joml/Quaternionfc;)Lorg/joml/Matrix4f;"))
|
||||
//#else
|
||||
//$$ @ModifyExpressionValue(method = "renderWorld", at = @At(value = "INVOKE", target = "Lorg/joml/Matrix4f;rotationXYZ(FFF)Lorg/joml/Matrix4f;"))
|
||||
//#endif
|
||||
//$$ private Matrix4f realLens_applyCameraTransform(Matrix4f matrix) {
|
||||
//#else
|
||||
@Inject(method = "renderWorld", at = @At("HEAD"))
|
||||
private void realLens_applyCameraTransform(float partialTicks, long frameStartNano, MatrixStack matrixStack, CallbackInfo ci) {
|
||||
//#endif
|
||||
|
||||
RealLensOpenGlFrameCapturer.Data cam = RealLensCameraContext.get();
|
||||
if (cam == null) {
|
||||
System.out.println("renderWorld WITHOUT camera context!");
|
||||
//#if MC>=12005
|
||||
//$$ return matrix;
|
||||
//#else
|
||||
return;
|
||||
//#endif
|
||||
}
|
||||
|
||||
//#if MC>=12005
|
||||
//$$ matrix.translateLocal(cam.dx, cam.dy, cam.dz);
|
||||
//#else
|
||||
matrixStack.translate(cam.dx, cam.dy, cam.dz);
|
||||
//#endif
|
||||
|
||||
//#if MC>=12005
|
||||
//$$ return matrix;
|
||||
//#endif
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
package com.replaymod.render.processor;
|
||||
|
||||
import com.replaymod.render.frame.BitmapFrame;
|
||||
import com.replaymod.render.frame.OpenGlFrame;
|
||||
import com.replaymod.render.frame.RealLensOpenGlFrame;
|
||||
import com.replaymod.render.utils.ByteBufferPool;
|
||||
import de.johni0702.minecraft.gui.utils.lwjgl.Dimension;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import static com.replaymod.render.utils.Utils.openGlBytesToBitmap;
|
||||
|
||||
public class RealLensToBitmapProcessor
|
||||
extends AbstractFrameProcessor<RealLensOpenGlFrame, BitmapFrame> {
|
||||
|
||||
@Override
|
||||
public BitmapFrame process(RealLensOpenGlFrame rawFrame) {
|
||||
|
||||
OpenGlFrame[] frames = rawFrame.getFrames();
|
||||
OpenGlFrame first = frames[0];
|
||||
|
||||
int width = first.getSize().getWidth();
|
||||
int height = first.getSize().getHeight();
|
||||
int bpp = first.getBytesPerPixel();
|
||||
|
||||
int totalBytes = width * height * bpp;
|
||||
|
||||
int[] accumulator = new int[totalBytes];
|
||||
|
||||
ByteBuffer converted = ByteBufferPool.allocate(totalBytes);
|
||||
|
||||
try {
|
||||
|
||||
for (OpenGlFrame frame : frames) {
|
||||
|
||||
converted.clear();
|
||||
|
||||
// BGRA -> bitmap layout (still BGRA at this point)
|
||||
openGlBytesToBitmap(
|
||||
frame,
|
||||
0,
|
||||
0,
|
||||
converted,
|
||||
width
|
||||
);
|
||||
|
||||
converted.rewind();
|
||||
|
||||
// accumulate per channel with B <-> R swap
|
||||
for (int i = 0; i < totalBytes; i += bpp) {
|
||||
|
||||
int b = converted.get(i) & 0xFF;
|
||||
int g = converted.get(i + 1) & 0xFF;
|
||||
int r = converted.get(i + 2) & 0xFF;
|
||||
int a = (bpp == 4) ? (converted.get(i + 3) & 0xFF) : 255;
|
||||
|
||||
// swap R and B here
|
||||
accumulator[i] += r;
|
||||
accumulator[i + 1] += g;
|
||||
accumulator[i + 2] += b;
|
||||
|
||||
if (bpp == 4) {
|
||||
accumulator[i + 3] += a;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ByteBuffer output = ByteBufferPool.allocate(totalBytes);
|
||||
|
||||
int samples = frames.length;
|
||||
|
||||
for (int i = 0; i < totalBytes; i += bpp) {
|
||||
|
||||
output.put((byte) (accumulator[i] / samples)); // R
|
||||
output.put((byte) (accumulator[i + 1] / samples)); // G
|
||||
output.put((byte) (accumulator[i + 2] / samples)); // B
|
||||
|
||||
if (bpp == 4) {
|
||||
output.put((byte) (accumulator[i + 3] / samples)); // A
|
||||
}
|
||||
}
|
||||
|
||||
output.rewind();
|
||||
|
||||
return new BitmapFrame(
|
||||
rawFrame.getFrameId(),
|
||||
new Dimension(width, height),
|
||||
bpp,
|
||||
output
|
||||
);
|
||||
|
||||
} finally {
|
||||
|
||||
ByteBufferPool.release(converted);
|
||||
|
||||
for (OpenGlFrame frame : frames) {
|
||||
ByteBufferPool.release(frame.getByteBuffer());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -24,6 +24,9 @@ import com.replaymod.render.processor.ODSToBitmapProcessor;
|
||||
import com.replaymod.render.processor.OpenGlToBitmapProcessor;
|
||||
import com.replaymod.render.processor.StereoscopicToBitmapProcessor;
|
||||
import com.replaymod.render.utils.PixelBufferObject;
|
||||
import com.replaymod.render.capturer.RealLensOpenGlFrameCapturer;
|
||||
import com.replaymod.render.frame.RealLensOpenGlFrame;
|
||||
import com.replaymod.render.processor.RealLensToBitmapProcessor;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@@ -32,6 +35,8 @@ public class Pipelines {
|
||||
switch (method) {
|
||||
case DEFAULT:
|
||||
return newDefaultPipeline(renderInfo, consumer);
|
||||
case REALLENS:
|
||||
return newRealLensPipeline(renderInfo, consumer);
|
||||
case STEREOSCOPIC:
|
||||
return newStereoscopicPipeline(renderInfo, consumer);
|
||||
case CUBIC:
|
||||
@@ -58,6 +63,15 @@ public class Pipelines {
|
||||
return new Pipeline<>(worldRenderer, capturer, new OpenGlToBitmapProcessor(), consumer);
|
||||
}
|
||||
|
||||
public static Pipeline<RealLensOpenGlFrame, BitmapFrame> newRealLensPipeline(
|
||||
RenderInfo renderInfo, FrameConsumer<BitmapFrame> consumer) {
|
||||
RenderSettings settings = renderInfo.getRenderSettings();
|
||||
WorldRenderer worldRenderer = new EntityRendererHandler(settings, renderInfo);
|
||||
FrameCapturer<RealLensOpenGlFrame> capturer =
|
||||
new RealLensOpenGlFrameCapturer(worldRenderer, renderInfo);
|
||||
return new Pipeline<>(worldRenderer, capturer, new RealLensToBitmapProcessor(), consumer);
|
||||
}
|
||||
|
||||
public static Pipeline<StereoscopicOpenGlFrame, BitmapFrame> newStereoscopicPipeline(RenderInfo renderInfo, FrameConsumer<BitmapFrame> consumer) {
|
||||
RenderSettings settings = renderInfo.getRenderSettings();
|
||||
WorldRenderer worldRenderer = new EntityRendererHandler(settings, renderInfo);
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
"Mixin_SkipBlockOutlinesDuringRender",
|
||||
"Mixin_SkipHudDuringRender",
|
||||
"Mixin_StabilizeCamera",
|
||||
"Mixin_RealLens_Camera",
|
||||
"Mixin_Stereoscopic_Camera",
|
||||
"Mixin_Stereoscopic_HandRenderPass",
|
||||
"Mixin_SuppressFramebufferResizeDuringRender",
|
||||
|
||||
0
versions/1.21.11/logs/latest.log
Normal file
0
versions/1.21.11/logs/latest.log
Normal file
Reference in New Issue
Block a user