Stop assuming that our render pipeline will only process RGB frames
For one, we have already switched to RGBA some time ago, so the name was technically incorrect already. But the main reason is that we'll want to use them for depth maps as well (and potentially maybe even for HDR images if that's possible with canvas?).
This commit is contained in:
@@ -4,7 +4,7 @@ import com.replaymod.core.ReplayMod;
|
||||
import com.replaymod.core.utils.Utils;
|
||||
import com.replaymod.core.versions.MCVer;
|
||||
import com.replaymod.extras.ReplayModExtras;
|
||||
import com.replaymod.render.frame.RGBFrame;
|
||||
import com.replaymod.render.frame.BitmapFrame;
|
||||
import com.replaymod.render.rendering.FrameConsumer;
|
||||
import com.replaymod.replay.ReplayModReplay;
|
||||
import de.johni0702.minecraft.gui.utils.lwjgl.ReadableDimension;
|
||||
@@ -14,7 +14,7 @@ import net.minecraft.util.crash.CrashReport;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
public class ScreenshotWriter implements FrameConsumer<RGBFrame> {
|
||||
public class ScreenshotWriter implements FrameConsumer<BitmapFrame> {
|
||||
|
||||
private final File outputFile;
|
||||
|
||||
@@ -23,7 +23,7 @@ public class ScreenshotWriter implements FrameConsumer<RGBFrame> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void consume(RGBFrame frame) {
|
||||
public void consume(BitmapFrame frame) {
|
||||
// skip the first frame, in which not all chunks are properly loaded
|
||||
if (frame.getFrameId() == 0) return;
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package com.replaymod.render;
|
||||
|
||||
import com.replaymod.core.versions.MCVer;
|
||||
import com.replaymod.render.frame.RGBFrame;
|
||||
import com.replaymod.render.frame.BitmapFrame;
|
||||
import com.replaymod.render.rendering.FrameConsumer;
|
||||
import com.replaymod.render.rendering.VideoRenderer;
|
||||
import com.replaymod.render.utils.ByteBufferPool;
|
||||
@@ -26,7 +26,7 @@ import java.util.concurrent.TimeUnit;
|
||||
import static com.replaymod.render.ReplayModRender.LOGGER;
|
||||
import static org.apache.commons.lang3.Validate.isTrue;
|
||||
|
||||
public class VideoWriter implements FrameConsumer<RGBFrame> {
|
||||
public class VideoWriter implements FrameConsumer<BitmapFrame> {
|
||||
|
||||
private final VideoRenderer renderer;
|
||||
private final RenderSettings settings;
|
||||
@@ -103,7 +103,7 @@ public class VideoWriter implements FrameConsumer<RGBFrame> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void consume(RGBFrame frame) {
|
||||
public void consume(BitmapFrame frame) {
|
||||
try {
|
||||
checkSize(frame.getSize());
|
||||
channel.write(frame.getByteBuffer());
|
||||
|
||||
@@ -3,14 +3,14 @@ package com.replaymod.render.blend;
|
||||
import com.replaymod.core.versions.MCVer;
|
||||
import com.replaymod.render.capturer.RenderInfo;
|
||||
import com.replaymod.render.capturer.WorldRenderer;
|
||||
import com.replaymod.render.frame.RGBFrame;
|
||||
import com.replaymod.render.frame.BitmapFrame;
|
||||
import com.replaymod.render.rendering.FrameCapturer;
|
||||
import com.replaymod.render.utils.ByteBufferPool;
|
||||
import de.johni0702.minecraft.gui.utils.lwjgl.Dimension;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class BlendFrameCapturer implements FrameCapturer<RGBFrame> {
|
||||
public class BlendFrameCapturer implements FrameCapturer<BitmapFrame> {
|
||||
protected final WorldRenderer worldRenderer;
|
||||
protected final RenderInfo renderInfo;
|
||||
protected int framesDone;
|
||||
@@ -26,7 +26,7 @@ public class BlendFrameCapturer implements FrameCapturer<RGBFrame> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public RGBFrame process() {
|
||||
public BitmapFrame process() {
|
||||
if (framesDone == 0) {
|
||||
BlendState.getState().setup();
|
||||
}
|
||||
@@ -37,7 +37,7 @@ public class BlendFrameCapturer implements FrameCapturer<RGBFrame> {
|
||||
worldRenderer.renderWorld(MCVer.getRenderPartialTicks(), null);
|
||||
BlendState.getState().postFrame(framesDone);
|
||||
|
||||
return new RGBFrame(framesDone++, new Dimension(0, 0), ByteBufferPool.allocate(0));
|
||||
return new BitmapFrame(framesDone++, new Dimension(0, 0), 0, ByteBufferPool.allocate(0));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -53,7 +53,7 @@ public abstract class MultiFramePboOpenGlFrameCapturer<F extends Frame, D extend
|
||||
pboBuffer.limit(pboBuffer.position() + frameBufferSize);
|
||||
frameBuffer.put(pboBuffer);
|
||||
frameBuffer.rewind();
|
||||
frames[i] = new OpenGlFrame(framesDone - 2, frameSize, frameBuffer);
|
||||
frames[i] = new OpenGlFrame(framesDone - 2, frameSize, 4, frameBuffer);
|
||||
}
|
||||
|
||||
pbo.unmap();
|
||||
|
||||
@@ -112,7 +112,7 @@ public abstract class OpenGlFrameCapturer<F extends Frame, D extends CaptureData
|
||||
frameBuffer().endWrite();
|
||||
buffer.rewind();
|
||||
|
||||
return new OpenGlFrame(frameId, new Dimension(getFrameWidth(), getFrameHeight()), buffer);
|
||||
return new OpenGlFrame(frameId, new Dimension(getFrameWidth(), getFrameHeight()), 4, buffer);
|
||||
}
|
||||
|
||||
protected void resize(int width, int height) {
|
||||
|
||||
@@ -47,7 +47,7 @@ public class SimplePboOpenGlFrameCapturer extends OpenGlFrameCapturer<OpenGlFram
|
||||
buffer.rewind();
|
||||
pbo.unmap();
|
||||
pbo.unbind();
|
||||
frame = new OpenGlFrame(framesDone - 2, frameSize, buffer);
|
||||
frame = new OpenGlFrame(framesDone - 2, frameSize, 4, buffer);
|
||||
}
|
||||
|
||||
if (framesDone < renderInfo.getTotalFrames()) {
|
||||
|
||||
@@ -6,19 +6,19 @@ import org.apache.commons.lang3.Validate;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
public class RGBFrame implements Frame {
|
||||
public class BitmapFrame implements Frame {
|
||||
private final int frameId;
|
||||
|
||||
private final ReadableDimension size;
|
||||
|
||||
private final int bytesPerPixel;
|
||||
private final ByteBuffer byteBuffer;
|
||||
|
||||
public RGBFrame(int frameId, ReadableDimension size, ByteBuffer byteBuffer) {
|
||||
Validate.isTrue(size.getWidth() * size.getHeight() * 4 == byteBuffer.remaining(),
|
||||
public BitmapFrame(int frameId, ReadableDimension size, int bytesPerPixel, ByteBuffer byteBuffer) {
|
||||
Validate.isTrue(size.getWidth() * size.getHeight() * bytesPerPixel == byteBuffer.remaining(),
|
||||
"Buffer size is %d (cap: %d) but should be %d",
|
||||
byteBuffer.remaining(), byteBuffer.capacity(), size.getWidth() * size.getHeight() * 4);
|
||||
byteBuffer.remaining(), byteBuffer.capacity(), size.getWidth() * size.getHeight() * bytesPerPixel);
|
||||
this.frameId = frameId;
|
||||
this.size = size;
|
||||
this.bytesPerPixel = bytesPerPixel;
|
||||
this.byteBuffer = byteBuffer;
|
||||
}
|
||||
|
||||
@@ -30,6 +30,10 @@ public class RGBFrame implements Frame {
|
||||
return this.size;
|
||||
}
|
||||
|
||||
public int getBytesPerPixel() {
|
||||
return bytesPerPixel;
|
||||
}
|
||||
|
||||
public ByteBuffer getByteBuffer() {
|
||||
return this.byteBuffer;
|
||||
}
|
||||
@@ -7,14 +7,14 @@ import java.nio.ByteBuffer;
|
||||
|
||||
public class OpenGlFrame implements Frame {
|
||||
private final int frameId;
|
||||
|
||||
private final ReadableDimension size;
|
||||
|
||||
private final int bytesPerPixel;
|
||||
private final ByteBuffer byteBuffer;
|
||||
|
||||
public OpenGlFrame(int frameId, ReadableDimension size, ByteBuffer byteBuffer) {
|
||||
public OpenGlFrame(int frameId, ReadableDimension size, int bytesPerPixel, ByteBuffer byteBuffer) {
|
||||
this.frameId = frameId;
|
||||
this.size = size;
|
||||
this.bytesPerPixel = bytesPerPixel;
|
||||
this.byteBuffer = byteBuffer;
|
||||
}
|
||||
|
||||
@@ -26,6 +26,10 @@ public class OpenGlFrame implements Frame {
|
||||
return this.size;
|
||||
}
|
||||
|
||||
public int getBytesPerPixel() {
|
||||
return bytesPerPixel;
|
||||
}
|
||||
|
||||
public ByteBuffer getByteBuffer() {
|
||||
return this.byteBuffer;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package com.replaymod.render.gui;
|
||||
|
||||
import com.replaymod.core.utils.Utils;
|
||||
import com.replaymod.render.frame.RGBFrame;
|
||||
import com.replaymod.render.frame.BitmapFrame;
|
||||
import com.replaymod.render.rendering.VideoRenderer;
|
||||
import de.johni0702.minecraft.gui.GuiRenderer;
|
||||
import de.johni0702.minecraft.gui.RenderInfo;
|
||||
@@ -265,7 +265,7 @@ public class GuiVideoRenderer extends GuiScreen implements Tickable {
|
||||
guiRenderer.drawTexturedRect(x, y, 0, 0, width, height, videoWidth, videoHeight, videoWidth, videoHeight);
|
||||
}
|
||||
|
||||
public void updatePreview(RGBFrame frame) {
|
||||
public void updatePreview(BitmapFrame frame) {
|
||||
if (previewCheckbox.isChecked() && previewTexture != null) {
|
||||
ByteBuffer buffer = frame.getByteBuffer();
|
||||
buffer.mark();
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
package com.replaymod.render.processor;
|
||||
|
||||
import com.replaymod.render.frame.CubicOpenGlFrame;
|
||||
import com.replaymod.render.frame.BitmapFrame;
|
||||
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 CubicToBitmapProcessor extends AbstractFrameProcessor<CubicOpenGlFrame, BitmapFrame> {
|
||||
|
||||
@Override
|
||||
public BitmapFrame process(CubicOpenGlFrame rawFrame) {
|
||||
int size = rawFrame.getLeft().getSize().getWidth();
|
||||
int bpp = rawFrame.getLeft().getBytesPerPixel();
|
||||
int width = size * 4;
|
||||
int height = size * 3;
|
||||
ByteBuffer result = ByteBufferPool.allocate(width * height * bpp);
|
||||
openGlBytesToBitmap(rawFrame.getLeft(), 0, size, result, width);
|
||||
openGlBytesToBitmap(rawFrame.getFront(), size, size, result, width);
|
||||
openGlBytesToBitmap(rawFrame.getRight(), size * 2, size, result, width);
|
||||
openGlBytesToBitmap(rawFrame.getBack(), size * 3, size, result, width);
|
||||
openGlBytesToBitmap(rawFrame.getTop(), size, 0, result, width);
|
||||
openGlBytesToBitmap(rawFrame.getBottom(), size, size * 2, result, width);
|
||||
ByteBufferPool.release(rawFrame.getLeft().getByteBuffer());
|
||||
ByteBufferPool.release(rawFrame.getRight().getByteBuffer());
|
||||
ByteBufferPool.release(rawFrame.getFront().getByteBuffer());
|
||||
ByteBufferPool.release(rawFrame.getBack().getByteBuffer());
|
||||
ByteBufferPool.release(rawFrame.getTop().getByteBuffer());
|
||||
ByteBufferPool.release(rawFrame.getBottom().getByteBuffer());
|
||||
return new BitmapFrame(rawFrame.getFrameId(), new Dimension(width, height), bpp, result);
|
||||
}
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
package com.replaymod.render.processor;
|
||||
|
||||
import com.replaymod.render.frame.CubicOpenGlFrame;
|
||||
import com.replaymod.render.frame.RGBFrame;
|
||||
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.openGlBytesToRBG;
|
||||
|
||||
public class CubicToRGBProcessor extends AbstractFrameProcessor<CubicOpenGlFrame, RGBFrame> {
|
||||
@Override
|
||||
public RGBFrame process(CubicOpenGlFrame rawFrame) {
|
||||
int size = rawFrame.getLeft().getSize().getWidth();
|
||||
int width = size * 4;
|
||||
int height = size * 3;
|
||||
ByteBuffer result = ByteBufferPool.allocate(width * height * 4);
|
||||
openGlBytesToRBG(rawFrame.getLeft().getByteBuffer(), size, 0, size, result, width);
|
||||
openGlBytesToRBG(rawFrame.getFront().getByteBuffer(), size, size, size, result, width);
|
||||
openGlBytesToRBG(rawFrame.getRight().getByteBuffer(), size, size * 2, size, result, width);
|
||||
openGlBytesToRBG(rawFrame.getBack().getByteBuffer(), size, size * 3, size, result, width);
|
||||
openGlBytesToRBG(rawFrame.getTop().getByteBuffer(), size, size, 0, result, width);
|
||||
openGlBytesToRBG(rawFrame.getBottom().getByteBuffer(), size, size, size * 2, result, width);
|
||||
ByteBufferPool.release(rawFrame.getLeft().getByteBuffer());
|
||||
ByteBufferPool.release(rawFrame.getRight().getByteBuffer());
|
||||
ByteBufferPool.release(rawFrame.getFront().getByteBuffer());
|
||||
ByteBufferPool.release(rawFrame.getBack().getByteBuffer());
|
||||
ByteBufferPool.release(rawFrame.getTop().getByteBuffer());
|
||||
ByteBufferPool.release(rawFrame.getBottom().getByteBuffer());
|
||||
return new RGBFrame(rawFrame.getFrameId(), new Dimension(width, height), result);
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
package com.replaymod.render.processor;
|
||||
|
||||
import com.replaymod.render.frame.CubicOpenGlFrame;
|
||||
import com.replaymod.render.frame.RGBFrame;
|
||||
import com.replaymod.render.frame.BitmapFrame;
|
||||
import com.replaymod.render.utils.ByteBufferPool;
|
||||
import de.johni0702.minecraft.gui.utils.lwjgl.Dimension;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
@@ -10,7 +10,7 @@ import java.nio.ByteBuffer;
|
||||
|
||||
import static java.lang.Math.PI;
|
||||
|
||||
public class EquirectangularToRGBProcessor extends AbstractFrameProcessor<CubicOpenGlFrame, RGBFrame> {
|
||||
public class EquirectangularToBitmapProcessor extends AbstractFrameProcessor<CubicOpenGlFrame, BitmapFrame> {
|
||||
private static final byte IMAGE_BACK = 0;
|
||||
private static final byte IMAGE_FRONT = 1;
|
||||
private static final byte IMAGE_LEFT = 2;
|
||||
@@ -26,7 +26,7 @@ public class EquirectangularToRGBProcessor extends AbstractFrameProcessor<CubicO
|
||||
private final int[][] imageX;
|
||||
private final int[][] imageY;
|
||||
|
||||
public EquirectangularToRGBProcessor(int outputWidth, int outputHeight, int sphericalFovX) {
|
||||
public EquirectangularToBitmapProcessor(int outputWidth, int outputHeight, int sphericalFovX) {
|
||||
// calculate the dimensions of the original equirectangular projection
|
||||
// (before cropping according to FOV)
|
||||
width = outputWidth;
|
||||
@@ -103,16 +103,17 @@ public class EquirectangularToRGBProcessor extends AbstractFrameProcessor<CubicO
|
||||
}
|
||||
|
||||
@Override
|
||||
public RGBFrame process(CubicOpenGlFrame rawFrame) {
|
||||
public BitmapFrame process(CubicOpenGlFrame rawFrame) {
|
||||
Validate.isTrue(rawFrame.getLeft().getSize().getWidth() == frameSize, "Frame size must be %d but was %d",
|
||||
frameSize, rawFrame.getLeft().getSize().getWidth());
|
||||
ByteBuffer result = ByteBufferPool.allocate(width * height * 4);
|
||||
int bpp = rawFrame.getLeft().getBytesPerPixel();
|
||||
ByteBuffer result = ByteBufferPool.allocate(width * height * bpp);
|
||||
ByteBuffer[] images = {
|
||||
rawFrame.getBack().getByteBuffer(), rawFrame.getFront().getByteBuffer(),
|
||||
rawFrame.getLeft().getByteBuffer(), rawFrame.getRight().getByteBuffer(),
|
||||
rawFrame.getTop().getByteBuffer(), rawFrame.getBottom().getByteBuffer()
|
||||
};
|
||||
byte[] pixel = new byte[4];
|
||||
byte[] pixel = new byte[bpp];
|
||||
byte[] image;
|
||||
int[] imageX, imageY;
|
||||
for (int y = 0; y < height; y++) {
|
||||
@@ -121,7 +122,7 @@ public class EquirectangularToRGBProcessor extends AbstractFrameProcessor<CubicO
|
||||
imageY = this.imageY[y];
|
||||
for (int x = 0; x < width; x++) {
|
||||
ByteBuffer source = images[image[x]];
|
||||
source.position((imageX[x] + imageY[x] * frameSize) * 4);
|
||||
source.position((imageX[x] + imageY[x] * frameSize) * bpp);
|
||||
source.get(pixel);
|
||||
result.put(pixel);
|
||||
}
|
||||
@@ -134,7 +135,7 @@ public class EquirectangularToRGBProcessor extends AbstractFrameProcessor<CubicO
|
||||
ByteBufferPool.release(rawFrame.getBack().getByteBuffer());
|
||||
ByteBufferPool.release(rawFrame.getTop().getByteBuffer());
|
||||
ByteBufferPool.release(rawFrame.getBottom().getByteBuffer());
|
||||
return new RGBFrame(rawFrame.getFrameId(), new Dimension(width, height), result);
|
||||
return new BitmapFrame(rawFrame.getFrameId(), new Dimension(width, height), bpp, result);
|
||||
}
|
||||
|
||||
public int getFrameSize() {
|
||||
@@ -1,7 +1,7 @@
|
||||
package com.replaymod.render.processor;
|
||||
|
||||
import com.replaymod.render.frame.ODSOpenGlFrame;
|
||||
import com.replaymod.render.frame.RGBFrame;
|
||||
import com.replaymod.render.frame.BitmapFrame;
|
||||
import com.replaymod.render.utils.ByteBufferPool;
|
||||
import de.johni0702.minecraft.gui.utils.lwjgl.Dimension;
|
||||
import de.johni0702.minecraft.gui.utils.lwjgl.ReadableDimension;
|
||||
@@ -9,25 +9,26 @@ import de.johni0702.minecraft.gui.utils.lwjgl.ReadableDimension;
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
public class ODSToRGBProcessor extends AbstractFrameProcessor<ODSOpenGlFrame, RGBFrame> {
|
||||
private final EquirectangularToRGBProcessor processor;
|
||||
public class ODSToBitmapProcessor extends AbstractFrameProcessor<ODSOpenGlFrame, BitmapFrame> {
|
||||
private final EquirectangularToBitmapProcessor processor;
|
||||
|
||||
public ODSToRGBProcessor(int outputWidth, int outputHeight, int sphericalFovX) {
|
||||
processor = new EquirectangularToRGBProcessor(outputWidth, outputHeight / 2, sphericalFovX);
|
||||
public ODSToBitmapProcessor(int outputWidth, int outputHeight, int sphericalFovX) {
|
||||
processor = new EquirectangularToBitmapProcessor(outputWidth, outputHeight / 2, sphericalFovX);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RGBFrame process(ODSOpenGlFrame rawFrame) {
|
||||
RGBFrame leftFrame = processor.process(rawFrame.getLeft());
|
||||
RGBFrame rightFrame = processor.process(rawFrame.getRight());
|
||||
public BitmapFrame process(ODSOpenGlFrame rawFrame) {
|
||||
BitmapFrame leftFrame = processor.process(rawFrame.getLeft());
|
||||
BitmapFrame rightFrame = processor.process(rawFrame.getRight());
|
||||
ReadableDimension size = new Dimension(leftFrame.getSize().getWidth(), leftFrame.getSize().getHeight() * 2);
|
||||
ByteBuffer result = ByteBufferPool.allocate(size.getWidth() * size.getHeight() * 4);
|
||||
int bpp = rawFrame.getLeft().getLeft().getBytesPerPixel();
|
||||
ByteBuffer result = ByteBufferPool.allocate(size.getWidth() * size.getHeight() * bpp);
|
||||
result.put(leftFrame.getByteBuffer());
|
||||
result.put(rightFrame.getByteBuffer());
|
||||
result.rewind();
|
||||
ByteBufferPool.release(leftFrame.getByteBuffer());
|
||||
ByteBufferPool.release(rightFrame.getByteBuffer());
|
||||
return new RGBFrame(rawFrame.getFrameId(), size, result);
|
||||
return new BitmapFrame(rawFrame.getFrameId(), size, bpp, result);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1,21 +1,22 @@
|
||||
package com.replaymod.render.processor;
|
||||
|
||||
import com.replaymod.render.frame.OpenGlFrame;
|
||||
import com.replaymod.render.frame.RGBFrame;
|
||||
import com.replaymod.render.frame.BitmapFrame;
|
||||
import de.johni0702.minecraft.gui.utils.lwjgl.ReadableDimension;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
public class OpenGlToRGBProcessor extends AbstractFrameProcessor<OpenGlFrame, RGBFrame> {
|
||||
public class OpenGlToBitmapProcessor extends AbstractFrameProcessor<OpenGlFrame, BitmapFrame> {
|
||||
|
||||
private byte[] row, rowSwap;
|
||||
|
||||
@Override
|
||||
public RGBFrame process(OpenGlFrame rawFrame) {
|
||||
public BitmapFrame process(OpenGlFrame rawFrame) {
|
||||
// Flip whole image in place
|
||||
|
||||
ReadableDimension size = rawFrame.getSize();
|
||||
int rowSize = size.getWidth() * 4;
|
||||
int bpp = rawFrame.getBytesPerPixel();
|
||||
int rowSize = size.getWidth() * bpp;
|
||||
if (row == null || row.length < rowSize) {
|
||||
row = new byte[rowSize];
|
||||
rowSwap = new byte[rowSize];
|
||||
@@ -37,6 +38,6 @@ public class OpenGlToRGBProcessor extends AbstractFrameProcessor<OpenGlFrame, RG
|
||||
buffer.put(rowSwap);
|
||||
}
|
||||
buffer.rewind();
|
||||
return new RGBFrame(rawFrame.getFrameId(), size, buffer);
|
||||
return new BitmapFrame(rawFrame.getFrameId(), size, bpp, buffer);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.replaymod.render.processor;
|
||||
|
||||
import com.replaymod.render.frame.BitmapFrame;
|
||||
import com.replaymod.render.frame.StereoscopicOpenGlFrame;
|
||||
import com.replaymod.render.utils.ByteBufferPool;
|
||||
import de.johni0702.minecraft.gui.utils.lwjgl.Dimension;
|
||||
import de.johni0702.minecraft.gui.utils.lwjgl.ReadableDimension;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import static com.replaymod.render.utils.Utils.openGlBytesToBitmap;
|
||||
|
||||
public class StereoscopicToBitmapProcessor extends AbstractFrameProcessor<StereoscopicOpenGlFrame, BitmapFrame> {
|
||||
@Override
|
||||
public BitmapFrame process(StereoscopicOpenGlFrame rawFrame) {
|
||||
ReadableDimension size = rawFrame.getLeft().getSize();
|
||||
int width = size.getWidth();
|
||||
int bpp = rawFrame.getLeft().getBytesPerPixel();
|
||||
ByteBuffer result = ByteBufferPool.allocate(width * 2 * size.getHeight() * bpp);
|
||||
openGlBytesToBitmap(rawFrame.getLeft(), 0, 0, result, width * 2);
|
||||
openGlBytesToBitmap(rawFrame.getRight(), size.getWidth(), 0, result, width * 2);
|
||||
ByteBufferPool.release(rawFrame.getLeft().getByteBuffer());
|
||||
ByteBufferPool.release(rawFrame.getRight().getByteBuffer());
|
||||
return new BitmapFrame(rawFrame.getFrameId(), new Dimension(width * 2, size.getHeight()), bpp, result);
|
||||
}
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
package com.replaymod.render.processor;
|
||||
|
||||
import com.replaymod.render.frame.RGBFrame;
|
||||
import com.replaymod.render.frame.StereoscopicOpenGlFrame;
|
||||
import com.replaymod.render.utils.ByteBufferPool;
|
||||
import de.johni0702.minecraft.gui.utils.lwjgl.Dimension;
|
||||
import de.johni0702.minecraft.gui.utils.lwjgl.ReadableDimension;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import static com.replaymod.render.utils.Utils.openGlBytesToRBG;
|
||||
|
||||
public class StereoscopicToRGBProcessor extends AbstractFrameProcessor<StereoscopicOpenGlFrame, RGBFrame> {
|
||||
@Override
|
||||
public RGBFrame process(StereoscopicOpenGlFrame rawFrame) {
|
||||
ReadableDimension size = rawFrame.getLeft().getSize();
|
||||
int width = size.getWidth();
|
||||
ByteBuffer leftBuffer = rawFrame.getLeft().getByteBuffer();
|
||||
ByteBuffer rightBuffer = rawFrame.getRight().getByteBuffer();
|
||||
ByteBuffer result = ByteBufferPool.allocate(width * 2 * size.getHeight() * 4);
|
||||
openGlBytesToRBG(leftBuffer, width, 0, 0, result, width * 2);
|
||||
openGlBytesToRBG(rightBuffer, width, size.getWidth(), 0, result, width * 2);
|
||||
ByteBufferPool.release(leftBuffer);
|
||||
ByteBufferPool.release(rightBuffer);
|
||||
return new RGBFrame(rawFrame.getFrameId(), new Dimension(width * 2, size.getHeight()), result);
|
||||
}
|
||||
}
|
||||
@@ -14,19 +14,19 @@ import com.replaymod.render.capturer.WorldRenderer;
|
||||
import com.replaymod.render.frame.CubicOpenGlFrame;
|
||||
import com.replaymod.render.frame.ODSOpenGlFrame;
|
||||
import com.replaymod.render.frame.OpenGlFrame;
|
||||
import com.replaymod.render.frame.RGBFrame;
|
||||
import com.replaymod.render.frame.BitmapFrame;
|
||||
import com.replaymod.render.frame.StereoscopicOpenGlFrame;
|
||||
import com.replaymod.render.hooks.EntityRendererHandler;
|
||||
import com.replaymod.render.processor.CubicToRGBProcessor;
|
||||
import com.replaymod.render.processor.CubicToBitmapProcessor;
|
||||
import com.replaymod.render.processor.DummyProcessor;
|
||||
import com.replaymod.render.processor.EquirectangularToRGBProcessor;
|
||||
import com.replaymod.render.processor.ODSToRGBProcessor;
|
||||
import com.replaymod.render.processor.OpenGlToRGBProcessor;
|
||||
import com.replaymod.render.processor.StereoscopicToRGBProcessor;
|
||||
import com.replaymod.render.processor.EquirectangularToBitmapProcessor;
|
||||
import com.replaymod.render.processor.ODSToBitmapProcessor;
|
||||
import com.replaymod.render.processor.OpenGlToBitmapProcessor;
|
||||
import com.replaymod.render.processor.StereoscopicToBitmapProcessor;
|
||||
import com.replaymod.render.utils.PixelBufferObject;
|
||||
|
||||
public class Pipelines {
|
||||
public static Pipeline newPipeline(RenderSettings.RenderMethod method, RenderInfo renderInfo, FrameConsumer<RGBFrame> consumer) {
|
||||
public static Pipeline newPipeline(RenderSettings.RenderMethod method, RenderInfo renderInfo, FrameConsumer<BitmapFrame> consumer) {
|
||||
switch (method) {
|
||||
case DEFAULT:
|
||||
return newDefaultPipeline(renderInfo, consumer);
|
||||
@@ -44,7 +44,7 @@ public class Pipelines {
|
||||
throw new UnsupportedOperationException("Unknown method: " + method);
|
||||
}
|
||||
|
||||
public static Pipeline<OpenGlFrame, RGBFrame> newDefaultPipeline(RenderInfo renderInfo, FrameConsumer<RGBFrame> consumer) {
|
||||
public static Pipeline<OpenGlFrame, BitmapFrame> newDefaultPipeline(RenderInfo renderInfo, FrameConsumer<BitmapFrame> consumer) {
|
||||
RenderSettings settings = renderInfo.getRenderSettings();
|
||||
WorldRenderer worldRenderer = new EntityRendererHandler(settings, renderInfo);
|
||||
FrameCapturer<OpenGlFrame> capturer;
|
||||
@@ -53,10 +53,10 @@ public class Pipelines {
|
||||
} else {
|
||||
capturer = new SimpleOpenGlFrameCapturer(worldRenderer, renderInfo);
|
||||
}
|
||||
return new Pipeline<>(worldRenderer, capturer, new OpenGlToRGBProcessor(), consumer);
|
||||
return new Pipeline<>(worldRenderer, capturer, new OpenGlToBitmapProcessor(), consumer);
|
||||
}
|
||||
|
||||
public static Pipeline<StereoscopicOpenGlFrame, RGBFrame> newStereoscopicPipeline(RenderInfo renderInfo, FrameConsumer<RGBFrame> consumer) {
|
||||
public static Pipeline<StereoscopicOpenGlFrame, BitmapFrame> newStereoscopicPipeline(RenderInfo renderInfo, FrameConsumer<BitmapFrame> consumer) {
|
||||
RenderSettings settings = renderInfo.getRenderSettings();
|
||||
WorldRenderer worldRenderer = new EntityRendererHandler(settings, renderInfo);
|
||||
FrameCapturer<StereoscopicOpenGlFrame> capturer;
|
||||
@@ -65,10 +65,10 @@ public class Pipelines {
|
||||
} else {
|
||||
capturer = new StereoscopicOpenGlFrameCapturer(worldRenderer, renderInfo);
|
||||
}
|
||||
return new Pipeline<>(worldRenderer, capturer, new StereoscopicToRGBProcessor(), consumer);
|
||||
return new Pipeline<>(worldRenderer, capturer, new StereoscopicToBitmapProcessor(), consumer);
|
||||
}
|
||||
|
||||
public static Pipeline<CubicOpenGlFrame, RGBFrame> newCubicPipeline(RenderInfo renderInfo, FrameConsumer<RGBFrame> consumer) {
|
||||
public static Pipeline<CubicOpenGlFrame, BitmapFrame> newCubicPipeline(RenderInfo renderInfo, FrameConsumer<BitmapFrame> consumer) {
|
||||
RenderSettings settings = renderInfo.getRenderSettings();
|
||||
WorldRenderer worldRenderer = new EntityRendererHandler(settings, renderInfo);
|
||||
FrameCapturer<CubicOpenGlFrame> capturer;
|
||||
@@ -77,14 +77,14 @@ public class Pipelines {
|
||||
} else {
|
||||
capturer = new CubicOpenGlFrameCapturer(worldRenderer, renderInfo, settings.getVideoWidth() / 4);
|
||||
}
|
||||
return new Pipeline<>(worldRenderer, capturer, new CubicToRGBProcessor(), consumer);
|
||||
return new Pipeline<>(worldRenderer, capturer, new CubicToBitmapProcessor(), consumer);
|
||||
}
|
||||
|
||||
public static Pipeline<CubicOpenGlFrame, RGBFrame> newEquirectangularPipeline(RenderInfo renderInfo, FrameConsumer<RGBFrame> consumer) {
|
||||
public static Pipeline<CubicOpenGlFrame, BitmapFrame> newEquirectangularPipeline(RenderInfo renderInfo, FrameConsumer<BitmapFrame> consumer) {
|
||||
RenderSettings settings = renderInfo.getRenderSettings();
|
||||
WorldRenderer worldRenderer = new EntityRendererHandler(settings, renderInfo);
|
||||
|
||||
EquirectangularToRGBProcessor processor = new EquirectangularToRGBProcessor(settings.getVideoWidth(),
|
||||
EquirectangularToBitmapProcessor processor = new EquirectangularToBitmapProcessor(settings.getVideoWidth(),
|
||||
settings.getVideoHeight(), settings.getSphericalFovX());
|
||||
|
||||
FrameCapturer<CubicOpenGlFrame> capturer;
|
||||
@@ -96,11 +96,11 @@ public class Pipelines {
|
||||
return new Pipeline<>(worldRenderer, capturer, processor, consumer);
|
||||
}
|
||||
|
||||
public static Pipeline<ODSOpenGlFrame, RGBFrame> newODSPipeline(RenderInfo renderInfo, FrameConsumer<RGBFrame> consumer) {
|
||||
public static Pipeline<ODSOpenGlFrame, BitmapFrame> newODSPipeline(RenderInfo renderInfo, FrameConsumer<BitmapFrame> consumer) {
|
||||
RenderSettings settings = renderInfo.getRenderSettings();
|
||||
WorldRenderer worldRenderer = new EntityRendererHandler(settings, renderInfo);
|
||||
|
||||
ODSToRGBProcessor processor = new ODSToRGBProcessor(settings.getVideoWidth(),
|
||||
ODSToBitmapProcessor processor = new ODSToBitmapProcessor(settings.getVideoWidth(),
|
||||
settings.getVideoHeight(), settings.getSphericalFovX());
|
||||
|
||||
FrameCapturer<ODSOpenGlFrame> capturer =
|
||||
@@ -108,13 +108,13 @@ public class Pipelines {
|
||||
return new Pipeline<>(worldRenderer, capturer, processor, consumer);
|
||||
}
|
||||
|
||||
public static Pipeline<RGBFrame, RGBFrame> newBlendPipeline(RenderInfo renderInfo) {
|
||||
public static Pipeline<BitmapFrame, BitmapFrame> newBlendPipeline(RenderInfo renderInfo) {
|
||||
RenderSettings settings = renderInfo.getRenderSettings();
|
||||
WorldRenderer worldRenderer = new EntityRendererHandler(settings, renderInfo);
|
||||
FrameCapturer<RGBFrame> capturer = new BlendFrameCapturer(worldRenderer, renderInfo);
|
||||
FrameConsumer<RGBFrame> consumer = new FrameConsumer<RGBFrame>() {
|
||||
FrameCapturer<BitmapFrame> capturer = new BlendFrameCapturer(worldRenderer, renderInfo);
|
||||
FrameConsumer<BitmapFrame> consumer = new FrameConsumer<BitmapFrame>() {
|
||||
@Override
|
||||
public void consume(RGBFrame frame) {
|
||||
public void consume(BitmapFrame frame) {
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -13,7 +13,7 @@ import com.replaymod.render.VideoWriter;
|
||||
import com.replaymod.render.blend.BlendState;
|
||||
import com.replaymod.render.capturer.RenderInfo;
|
||||
import com.replaymod.render.events.ReplayRenderCallback;
|
||||
import com.replaymod.render.frame.RGBFrame;
|
||||
import com.replaymod.render.frame.BitmapFrame;
|
||||
import com.replaymod.render.gui.GuiRenderingDone;
|
||||
import com.replaymod.render.gui.GuiVideoRenderer;
|
||||
import com.replaymod.render.metadata.MetadataInjector;
|
||||
@@ -124,7 +124,7 @@ public class VideoRenderer implements RenderInfo {
|
||||
this.renderingPipeline = Pipelines.newPipeline(settings.getRenderMethod(), this,
|
||||
videoWriter = new VideoWriter(this) {
|
||||
@Override
|
||||
public void consume(RGBFrame frame) {
|
||||
public void consume(BitmapFrame frame) {
|
||||
gui.updatePreview(frame);
|
||||
super.consume(frame);
|
||||
}
|
||||
|
||||
@@ -1,24 +1,41 @@
|
||||
package com.replaymod.render.utils;
|
||||
|
||||
import com.replaymod.render.frame.OpenGlFrame;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
public class Utils {
|
||||
/**
|
||||
* Copies the rgb image (flipped vertically) to the specified position in the target buffer
|
||||
* @param buffer Source image
|
||||
* @param bufferWidth Source image width
|
||||
* @param source Source image
|
||||
* @param xOffset X offset in target image
|
||||
* @param yOffset Y offset in target image
|
||||
* @param to Target image
|
||||
* @param width Target image width
|
||||
*/
|
||||
public static void openGlBytesToRBG(ByteBuffer buffer, int bufferWidth, int xOffset, int yOffset, ByteBuffer to, int width) {
|
||||
byte[] rowBuf = new byte[bufferWidth * 4];
|
||||
public static void openGlBytesToBitmap(OpenGlFrame source, int xOffset, int yOffset, ByteBuffer to, int width) {
|
||||
openGlBytesToBitmap(
|
||||
source.getByteBuffer(), source.getSize().getWidth(), source.getBytesPerPixel(),
|
||||
xOffset, yOffset, to, width);
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies the rgb image (flipped vertically) to the specified position in the target buffer
|
||||
* @param buffer Source image
|
||||
* @param bufferWidth Source image width
|
||||
* @param bbp Bytes per pixel
|
||||
* @param xOffset X offset in target image
|
||||
* @param yOffset Y offset in target image
|
||||
* @param to Target image
|
||||
* @param width Target image width
|
||||
*/
|
||||
public static void openGlBytesToBitmap(ByteBuffer buffer, int bufferWidth, int bbp, int xOffset, int yOffset, ByteBuffer to, int width) {
|
||||
byte[] rowBuf = new byte[bufferWidth * bbp];
|
||||
// Copy image flipped vertically to target buffer
|
||||
int rows = buffer.remaining() / 4 / bufferWidth;
|
||||
int rows = buffer.remaining() / bbp / bufferWidth;
|
||||
for (int i = 0; i < rows; i++) {
|
||||
buffer.get(rowBuf);
|
||||
to.position(((yOffset + rows - i - 1) * width + xOffset) * 4);
|
||||
to.position(((yOffset + rows - i - 1) * width + xOffset) * bbp);
|
||||
to.put(rowBuf);
|
||||
}
|
||||
to.rewind();
|
||||
|
||||
Reference in New Issue
Block a user