test worked
This commit is contained in:
@@ -25,7 +25,7 @@ import static com.replaymod.render.ReplayModRender.LOGGER;
|
|||||||
|
|
||||||
public class RenderSettings {
|
public class RenderSettings {
|
||||||
public enum RenderMethod {
|
public enum RenderMethod {
|
||||||
DEFAULT, STEREOSCOPIC, CUBIC, EQUIRECTANGULAR, ODS, BLEND;
|
DEFAULT, REALLENS, STEREOSCOPIC, CUBIC, EQUIRECTANGULAR, ODS, BLEND;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
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.OpenGlToBitmapProcessor;
|
||||||
import com.replaymod.render.processor.StereoscopicToBitmapProcessor;
|
import com.replaymod.render.processor.StereoscopicToBitmapProcessor;
|
||||||
import com.replaymod.render.utils.PixelBufferObject;
|
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;
|
import java.util.Map;
|
||||||
|
|
||||||
@@ -32,6 +35,8 @@ public class Pipelines {
|
|||||||
switch (method) {
|
switch (method) {
|
||||||
case DEFAULT:
|
case DEFAULT:
|
||||||
return newDefaultPipeline(renderInfo, consumer);
|
return newDefaultPipeline(renderInfo, consumer);
|
||||||
|
case REALLENS:
|
||||||
|
return newRealLensPipeline(renderInfo, consumer);
|
||||||
case STEREOSCOPIC:
|
case STEREOSCOPIC:
|
||||||
return newStereoscopicPipeline(renderInfo, consumer);
|
return newStereoscopicPipeline(renderInfo, consumer);
|
||||||
case CUBIC:
|
case CUBIC:
|
||||||
@@ -58,6 +63,15 @@ public class Pipelines {
|
|||||||
return new Pipeline<>(worldRenderer, capturer, new OpenGlToBitmapProcessor(), consumer);
|
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) {
|
public static Pipeline<StereoscopicOpenGlFrame, BitmapFrame> newStereoscopicPipeline(RenderInfo renderInfo, FrameConsumer<BitmapFrame> consumer) {
|
||||||
RenderSettings settings = renderInfo.getRenderSettings();
|
RenderSettings settings = renderInfo.getRenderSettings();
|
||||||
WorldRenderer worldRenderer = new EntityRendererHandler(settings, renderInfo);
|
WorldRenderer worldRenderer = new EntityRendererHandler(settings, renderInfo);
|
||||||
|
|||||||
@@ -31,6 +31,7 @@
|
|||||||
"Mixin_SkipBlockOutlinesDuringRender",
|
"Mixin_SkipBlockOutlinesDuringRender",
|
||||||
"Mixin_SkipHudDuringRender",
|
"Mixin_SkipHudDuringRender",
|
||||||
"Mixin_StabilizeCamera",
|
"Mixin_StabilizeCamera",
|
||||||
|
"Mixin_RealLens_Camera",
|
||||||
"Mixin_Stereoscopic_Camera",
|
"Mixin_Stereoscopic_Camera",
|
||||||
"Mixin_Stereoscopic_HandRenderPass",
|
"Mixin_Stereoscopic_HandRenderPass",
|
||||||
"Mixin_SuppressFramebufferResizeDuringRender",
|
"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