Use RGB instead of ARGB for export and therefore speed up OpenGL to output conversion process

This commit is contained in:
johni0702
2015-07-16 18:14:05 +02:00
parent a19317ecdd
commit 56efc8c5ec
12 changed files with 111 additions and 97 deletions

View File

@@ -4,7 +4,7 @@ import eu.crushedpixel.replaymod.gui.elements.GuiProgressBar;
import eu.crushedpixel.replaymod.utils.BoundingUtils;
import eu.crushedpixel.replaymod.utils.DurationUtils;
import eu.crushedpixel.replaymod.video.VideoRenderer;
import eu.crushedpixel.replaymod.video.frame.ARGBFrame;
import eu.crushedpixel.replaymod.video.frame.RGBFrame;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.gui.GuiScreen;
@@ -234,7 +234,7 @@ public class GuiVideoRenderer extends GuiScreen {
drawScaledCustomSizeModalRect(x, y, 0, 0, 1280, 720, actualWidth, actualHeight, 1280, 720);
}
public void updatePreview(ARGBFrame frame) {
public void updatePreview(RGBFrame frame) {
if (previewCheckBox.isChecked() && previewTexture != null) {
ByteBuffer buffer = frame.getByteBuffer();
buffer.mark();

View File

@@ -9,22 +9,22 @@ import net.minecraft.client.resources.I18n;
public enum EncodingPreset implements GuiEntryListEntry {
MP4CUSTOM("replaymod.gui.rendersettings.presets.mp4.custom",
"-f rawvideo -pix_fmt argb -s %WIDTH%x%HEIGHT% -r %FPS% -i - -an -c:v libx264 -b:v %BITRATE% -pix_fmt yuv420p %FILENAME%.mp4", "mp4"),
"-f rawvideo -pix_fmt rgb24 -s %WIDTH%x%HEIGHT% -r %FPS% -i - -an -c:v libx264 -b:v %BITRATE% -pix_fmt yuv420p %FILENAME%.mp4", "mp4"),
MP4HIGH("replaymod.gui.rendersettings.presets.mp4.high",
"-f rawvideo -pix_fmt argb -s %WIDTH%x%HEIGHT% -r %FPS% -i - -an -c:v libx264 -preset ultrafast -qp 1 -pix_fmt yuv420p %FILENAME%.mp4", "mp4"),
"-f rawvideo -pix_fmt rgb24 -s %WIDTH%x%HEIGHT% -r %FPS% -i - -an -c:v libx264 -preset ultrafast -qp 1 -pix_fmt yuv420p %FILENAME%.mp4", "mp4"),
MP4DEFAULT("replaymod.gui.rendersettings.presets.mp4.default",
"-f rawvideo -pix_fmt argb -s %WIDTH%x%HEIGHT% -r %FPS% -i - -an -c:v libx264 -preset ultrafast -pix_fmt yuv420p %FILENAME%.mp4", "mp4"),
"-f rawvideo -pix_fmt rgb24 -s %WIDTH%x%HEIGHT% -r %FPS% -i - -an -c:v libx264 -preset ultrafast -pix_fmt yuv420p %FILENAME%.mp4", "mp4"),
MP4POTATO("replaymod.gui.rendersettings.presets.mp4.potato",
"-f rawvideo -pix_fmt argb -s %WIDTH%x%HEIGHT% -r %FPS% -i - -an -c:v libx264 -preset ultrafast -crf 51 -pix_fmt yuv420p %FILENAME%.mp4", "mp4"),
"-f rawvideo -pix_fmt rgb24 -s %WIDTH%x%HEIGHT% -r %FPS% -i - -an -c:v libx264 -preset ultrafast -crf 51 -pix_fmt yuv420p %FILENAME%.mp4", "mp4"),
WEBMCUSTOM("replaymod.gui.rendersettings.presets.webm.custom",
"-f rawvideo -pix_fmt argb -s %WIDTH%x%HEIGHT% -r %FPS% -i - -an -c:v libvpx -b:v %BITRATE% %FILENAME%.webm", "webm"),
"-f rawvideo -pix_fmt rgb24 -s %WIDTH%x%HEIGHT% -r %FPS% -i - -an -c:v libvpx -b:v %BITRATE% %FILENAME%.webm", "webm"),
MKVLOSSLESS("replaymod.gui.rendersettings.presets.mkv.lossless",
"-f rawvideo -pix_fmt argb -s %WIDTH%x%HEIGHT% -r %FPS% -i - -an -c:v libx264 -preset ultrafast -qp 0 %FILENAME%.mkv", "mkv");
"-f rawvideo -pix_fmt rgb24 -s %WIDTH%x%HEIGHT% -r %FPS% -i - -an -c:v libx264 -preset ultrafast -qp 0 %FILENAME%.mkv", "mkv");
private String name;

View File

@@ -25,19 +25,14 @@ public class OpenGLUtils {
public static void init() {
}
public static void openGlBytesToARBG(ByteBuffer buffer, int bufferWidth, int xOffset, int yOffset, ByteBuffer to, int width) {
byte[] pixel = new byte[4];
pixel[0] = (byte) 0xff;
int bufferSize = buffer.remaining() / 3;
// Read the OpenGL image row by row from right to left (flipped horizontally)
for (int i = bufferSize - 1; i >= 0; i--) {
// Coordinates in the final image
int x = xOffset + bufferWidth - i % bufferWidth - 1; // X coord of OpenGL image has to be flipped first
int y = yOffset + i / bufferWidth;
// Write to image (row by row, left to right)
buffer.get(pixel, 1, 3);
to.position((y * width + x) * 4);
to.put(pixel);
public static void openGlBytesToRBG(ByteBuffer buffer, int bufferWidth, int xOffset, int yOffset, ByteBuffer to, int width) {
byte[] rowBuf = new byte[bufferWidth * 3];
// Copy image flipped vertically to target buffer
int rows = buffer.remaining() / 3 / bufferWidth;
for (int i = 0; i < rows; i++) {
buffer.get(rowBuf);
to.position(((yOffset + rows - i - 1) * width + xOffset) * 3);
to.put(rowBuf);
}
to.rewind();
}

View File

@@ -17,7 +17,7 @@ import eu.crushedpixel.replaymod.settings.RenderOptions;
import eu.crushedpixel.replaymod.timer.EnchantmentTimer;
import eu.crushedpixel.replaymod.timer.ReplayTimer;
import eu.crushedpixel.replaymod.video.capturer.RenderInfo;
import eu.crushedpixel.replaymod.video.frame.ARGBFrame;
import eu.crushedpixel.replaymod.video.frame.RGBFrame;
import eu.crushedpixel.replaymod.video.rendering.Pipeline;
import eu.crushedpixel.replaymod.video.rendering.Pipelines;
import net.minecraft.client.Minecraft;
@@ -62,7 +62,7 @@ public class VideoRenderer implements RenderInfo {
this.options = options;
this.renderingPipeline = Pipelines.newPipeline(options.getMode(), this, new VideoWriter(options) {
@Override
public void consume(ARGBFrame frame) {
public void consume(RGBFrame frame) {
gui.updatePreview(frame);
super.consume(frame);
}

View File

@@ -4,7 +4,7 @@ import eu.crushedpixel.replaymod.settings.RenderOptions;
import eu.crushedpixel.replaymod.utils.ByteBufferPool;
import eu.crushedpixel.replaymod.utils.StreamPipe;
import eu.crushedpixel.replaymod.utils.StringUtils;
import eu.crushedpixel.replaymod.video.frame.ARGBFrame;
import eu.crushedpixel.replaymod.video.frame.RGBFrame;
import eu.crushedpixel.replaymod.video.rendering.FrameConsumer;
import net.minecraft.client.Minecraft;
import net.minecraft.crash.CrashReport;
@@ -24,7 +24,7 @@ import java.util.concurrent.TimeUnit;
import static org.apache.commons.lang3.Validate.isTrue;
public class VideoWriter implements FrameConsumer<ARGBFrame> {
public class VideoWriter implements FrameConsumer<RGBFrame> {
private final RenderOptions options;
private final Process process;
@@ -84,7 +84,7 @@ public class VideoWriter implements FrameConsumer<ARGBFrame> {
}
@Override
public void consume(ARGBFrame frame) {
public void consume(RGBFrame frame) {
try {
checkSize(frame.getSize());
channel.write(frame.getByteBuffer());

View File

@@ -7,7 +7,7 @@ import org.lwjgl.util.ReadableDimension;
import java.nio.ByteBuffer;
public class ARGBFrame implements Frame {
public class RGBFrame implements Frame {
@Getter
private final int frameId;
@@ -17,8 +17,8 @@ public class ARGBFrame implements Frame {
@Getter
private final ByteBuffer byteBuffer;
public ARGBFrame(int frameId, ReadableDimension size, ByteBuffer byteBuffer) {
Validate.isTrue(size.getWidth() * size.getHeight() * 4 == byteBuffer.remaining(),
public RGBFrame(int frameId, ReadableDimension size, ByteBuffer byteBuffer) {
Validate.isTrue(size.getWidth() * size.getHeight() * 3 == byteBuffer.remaining(),
"Buffer size is %d (cap: %d) but should be %d",
byteBuffer.remaining(), byteBuffer.capacity(), size.getWidth() * size.getHeight() * 4);
this.frameId = frameId;

View File

@@ -1,33 +1,33 @@
package eu.crushedpixel.replaymod.video.processor;
import eu.crushedpixel.replaymod.utils.ByteBufferPool;
import eu.crushedpixel.replaymod.video.frame.ARGBFrame;
import eu.crushedpixel.replaymod.video.frame.CubicOpenGlFrame;
import eu.crushedpixel.replaymod.video.frame.RGBFrame;
import org.lwjgl.util.Dimension;
import java.nio.ByteBuffer;
import static eu.crushedpixel.replaymod.utils.OpenGLUtils.openGlBytesToARBG;
import static eu.crushedpixel.replaymod.utils.OpenGLUtils.openGlBytesToRBG;
public class CubicToARGBProcessor extends AbstractFrameProcessor<CubicOpenGlFrame, ARGBFrame> {
public class CubicToRGBProcessor extends AbstractFrameProcessor<CubicOpenGlFrame, RGBFrame> {
@Override
public ARGBFrame process(CubicOpenGlFrame rawFrame) {
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);
openGlBytesToARBG(rawFrame.getLeft().getByteBuffer(), size, 0, size, result, width);
openGlBytesToARBG(rawFrame.getFront().getByteBuffer(), size, size, size, result, width);
openGlBytesToARBG(rawFrame.getRight().getByteBuffer(), size, size * 2, size, result, width);
openGlBytesToARBG(rawFrame.getBack().getByteBuffer(), size, size * 3, size, result, width);
openGlBytesToARBG(rawFrame.getTop().getByteBuffer(), size, size, 0, result, width);
openGlBytesToARBG(rawFrame.getBottom().getByteBuffer(), size, size, size * 2, result, width);
ByteBuffer result = ByteBufferPool.allocate(width * height * 3);
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 ARGBFrame(rawFrame.getFrameId(), new Dimension(width, height), result);
return new RGBFrame(rawFrame.getFrameId(), new Dimension(width, height), result);
}
}

View File

@@ -1,8 +1,8 @@
package eu.crushedpixel.replaymod.video.processor;
import eu.crushedpixel.replaymod.utils.ByteBufferPool;
import eu.crushedpixel.replaymod.video.frame.ARGBFrame;
import eu.crushedpixel.replaymod.video.frame.CubicOpenGlFrame;
import eu.crushedpixel.replaymod.video.frame.RGBFrame;
import org.apache.commons.lang3.Validate;
import org.lwjgl.util.Dimension;
@@ -10,7 +10,7 @@ import java.nio.ByteBuffer;
import static java.lang.Math.PI;
public class EquirectangularToARGBProcessor extends AbstractFrameProcessor<CubicOpenGlFrame, ARGBFrame> {
public class EquirectangularToRGBProcessor extends AbstractFrameProcessor<CubicOpenGlFrame, RGBFrame> {
private static final byte IMAGE_BACK = 0;
private static final byte IMAGE_FRONT = 1;
private static final byte IMAGE_LEFT = 2;
@@ -27,7 +27,7 @@ public class EquirectangularToARGBProcessor extends AbstractFrameProcessor<Cubic
private final int[][] imageY;
public EquirectangularToARGBProcessor(int frameSize) {
public EquirectangularToRGBProcessor(int frameSize) {
this.frameSize = frameSize;
width = frameSize * 4;
@@ -82,17 +82,16 @@ public class EquirectangularToARGBProcessor extends AbstractFrameProcessor<Cubic
}
@Override
public ARGBFrame process(CubicOpenGlFrame rawFrame) {
public RGBFrame 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);
ByteBuffer result = ByteBufferPool.allocate(width * height * 3);
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];
pixel[0] = (byte) 0xff;
byte[] pixel = new byte[3];
byte[] image;
int[] imageX, imageY;
for (int y = 0; y < height; y++) {
@@ -102,7 +101,7 @@ public class EquirectangularToARGBProcessor extends AbstractFrameProcessor<Cubic
for (int x = 0; x < width; x++) {
ByteBuffer source = images[image[x]];
source.position((imageX[x] + imageY[x] * frameSize) * 3);
source.get(pixel, 1, 3);
source.get(pixel);
result.put(pixel);
}
}
@@ -114,6 +113,6 @@ public class EquirectangularToARGBProcessor extends AbstractFrameProcessor<Cubic
ByteBufferPool.release(rawFrame.getBack().getByteBuffer());
ByteBufferPool.release(rawFrame.getTop().getByteBuffer());
ByteBufferPool.release(rawFrame.getBottom().getByteBuffer());
return new ARGBFrame(rawFrame.getFrameId(), new Dimension(width, height), result);
return new RGBFrame(rawFrame.getFrameId(), new Dimension(width, height), result);
}
}

View File

@@ -1,22 +0,0 @@
package eu.crushedpixel.replaymod.video.processor;
import eu.crushedpixel.replaymod.utils.ByteBufferPool;
import eu.crushedpixel.replaymod.video.frame.ARGBFrame;
import eu.crushedpixel.replaymod.video.frame.OpenGlFrame;
import org.lwjgl.util.ReadableDimension;
import java.nio.ByteBuffer;
import static eu.crushedpixel.replaymod.utils.OpenGLUtils.openGlBytesToARBG;
public class OpenGlToARGBProcessor extends AbstractFrameProcessor<OpenGlFrame, ARGBFrame> {
@Override
public ARGBFrame process(OpenGlFrame rawFrame) {
ReadableDimension size = rawFrame.getSize();
ByteBuffer buffer = rawFrame.getByteBuffer();
ByteBuffer argb = ByteBufferPool.allocate(size.getWidth() * size.getHeight() * 4);
openGlBytesToARBG(buffer, size.getWidth(), 0, 0, argb, size.getWidth());
ByteBufferPool.release(buffer);
return new ARGBFrame(rawFrame.getFrameId(), size, argb);
}
}

View File

@@ -0,0 +1,42 @@
package eu.crushedpixel.replaymod.video.processor;
import eu.crushedpixel.replaymod.video.frame.OpenGlFrame;
import eu.crushedpixel.replaymod.video.frame.RGBFrame;
import org.lwjgl.util.ReadableDimension;
import java.nio.ByteBuffer;
public class OpenGlToRGBProcessor extends AbstractFrameProcessor<OpenGlFrame, RGBFrame> {
private byte[] row, rowSwap;
@Override
public RGBFrame process(OpenGlFrame rawFrame) {
// Flip whole image in place
ReadableDimension size = rawFrame.getSize();
int rowSize = size.getWidth() * 3;
if (row == null || row.length < rowSize) {
row = new byte[rowSize];
rowSwap = new byte[rowSize];
}
ByteBuffer buffer = rawFrame.getByteBuffer();
int rows = size.getHeight();
byte[] row = this.row;
byte[] rowSwap = this.rowSwap;
for (int i = 0; i < rows / 2; i++) {
int from = rowSize * i;
int to = rowSize * (rows - i - 1);
buffer.position(from);
buffer.get(row);
buffer.position(to);
buffer.get(rowSwap);
buffer.position(to);
buffer.put(row);
buffer.position(from);
buffer.put(rowSwap);
}
buffer.rewind();
return new RGBFrame(rawFrame.getFrameId(), size, buffer);
}
}

View File

@@ -1,27 +1,27 @@
package eu.crushedpixel.replaymod.video.processor;
import eu.crushedpixel.replaymod.utils.ByteBufferPool;
import eu.crushedpixel.replaymod.video.frame.ARGBFrame;
import eu.crushedpixel.replaymod.video.frame.RGBFrame;
import eu.crushedpixel.replaymod.video.frame.StereoscopicOpenGlFrame;
import org.lwjgl.util.Dimension;
import org.lwjgl.util.ReadableDimension;
import java.nio.ByteBuffer;
import static eu.crushedpixel.replaymod.utils.OpenGLUtils.openGlBytesToARBG;
import static eu.crushedpixel.replaymod.utils.OpenGLUtils.openGlBytesToRBG;
public class StereoscopicToARGBProcessor extends AbstractFrameProcessor<StereoscopicOpenGlFrame, ARGBFrame> {
public class StereoscopicToRGBProcessor extends AbstractFrameProcessor<StereoscopicOpenGlFrame, RGBFrame> {
@Override
public ARGBFrame process(StereoscopicOpenGlFrame rawFrame) {
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);
openGlBytesToARBG(leftBuffer, width, 0, 0, result, width * 2);
openGlBytesToARBG(rightBuffer, width, size.getWidth(), 0, result, width * 2);
ByteBuffer result = ByteBufferPool.allocate(width * 2 * size.getHeight() * 3);
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 ARGBFrame(rawFrame.getFrameId(), new Dimension(width * 2, size.getHeight()), result);
return new RGBFrame(rawFrame.getFrameId(), new Dimension(width * 2, size.getHeight()), result);
}
}

View File

@@ -6,14 +6,14 @@ 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.ARGBFrame;
import eu.crushedpixel.replaymod.video.frame.CubicOpenGlFrame;
import eu.crushedpixel.replaymod.video.frame.OpenGlFrame;
import eu.crushedpixel.replaymod.video.frame.RGBFrame;
import eu.crushedpixel.replaymod.video.frame.StereoscopicOpenGlFrame;
import eu.crushedpixel.replaymod.video.processor.CubicToARGBProcessor;
import eu.crushedpixel.replaymod.video.processor.EquirectangularToARGBProcessor;
import eu.crushedpixel.replaymod.video.processor.OpenGlToARGBProcessor;
import eu.crushedpixel.replaymod.video.processor.StereoscopicToARGBProcessor;
import eu.crushedpixel.replaymod.video.processor.CubicToRGBProcessor;
import eu.crushedpixel.replaymod.video.processor.EquirectangularToRGBProcessor;
import eu.crushedpixel.replaymod.video.processor.OpenGlToRGBProcessor;
import eu.crushedpixel.replaymod.video.processor.StereoscopicToRGBProcessor;
import lombok.experimental.UtilityClass;
@UtilityClass
@@ -22,7 +22,7 @@ public class Pipelines {
DEFAULT, STEREOSCOPIC, CUBIC, EQUIRECTANGULAR
}
public static Pipeline newPipeline(Preset preset, RenderInfo renderInfo, FrameConsumer<ARGBFrame> consumer) {
public static Pipeline newPipeline(Preset preset, RenderInfo renderInfo, FrameConsumer<RGBFrame> consumer) {
switch (preset) {
case DEFAULT:
return newDefaultPipeline(renderInfo, consumer);
@@ -36,7 +36,7 @@ public class Pipelines {
throw new UnsupportedOperationException("Unknown preset: " + preset);
}
public static Pipeline<OpenGlFrame, ARGBFrame> newDefaultPipeline(RenderInfo renderInfo, FrameConsumer<ARGBFrame> consumer) {
public static Pipeline<OpenGlFrame, RGBFrame> newDefaultPipeline(RenderInfo renderInfo, FrameConsumer<RGBFrame> consumer) {
RenderOptions options = renderInfo.getRenderOptions();
FrameCapturer<OpenGlFrame> capturer;
if (PixelBufferObject.SUPPORTED) {
@@ -44,32 +44,32 @@ public class Pipelines {
} else {
capturer = new SimpleOpenGlFrameCapturer(new CustomEntityRenderer<CaptureData>(options), renderInfo);
}
return new Pipeline<OpenGlFrame, ARGBFrame>(capturer, new OpenGlToARGBProcessor(), consumer);
return new Pipeline<OpenGlFrame, RGBFrame>(capturer, new OpenGlToRGBProcessor(), consumer);
}
public static Pipeline<StereoscopicOpenGlFrame, ARGBFrame> newStereoscopicPipeline(RenderInfo renderInfo, FrameConsumer<ARGBFrame> consumer) {
public static Pipeline<StereoscopicOpenGlFrame, RGBFrame> newStereoscopicPipeline(RenderInfo renderInfo, FrameConsumer<RGBFrame> consumer) {
RenderOptions options = renderInfo.getRenderOptions();
return new Pipeline<StereoscopicOpenGlFrame, ARGBFrame>(
return new Pipeline<StereoscopicOpenGlFrame, RGBFrame>(
new StereoscopicOpenGlFrameCapturer(new StereoscopicEntityRenderer(options), renderInfo),
new StereoscopicToARGBProcessor(),
new StereoscopicToRGBProcessor(),
consumer
);
}
public static Pipeline<CubicOpenGlFrame, ARGBFrame> newCubicPipeline(RenderInfo renderInfo, FrameConsumer<ARGBFrame> consumer) {
public static Pipeline<CubicOpenGlFrame, RGBFrame> newCubicPipeline(RenderInfo renderInfo, FrameConsumer<RGBFrame> consumer) {
RenderOptions options = renderInfo.getRenderOptions();
return new Pipeline<CubicOpenGlFrame, ARGBFrame>(
return new Pipeline<CubicOpenGlFrame, RGBFrame>(
new CubicOpenGlFrameCapturer(new CubicEntityRenderer(options), renderInfo, options.getWidth() / 4),
new CubicToARGBProcessor(),
new CubicToRGBProcessor(),
consumer
);
}
public static Pipeline<CubicOpenGlFrame, ARGBFrame> newEquirectangularPipeline(RenderInfo renderInfo, FrameConsumer<ARGBFrame> consumer) {
public static Pipeline<CubicOpenGlFrame, RGBFrame> newEquirectangularPipeline(RenderInfo renderInfo, FrameConsumer<RGBFrame> consumer) {
RenderOptions options = renderInfo.getRenderOptions();
return new Pipeline<CubicOpenGlFrame, ARGBFrame>(
return new Pipeline<CubicOpenGlFrame, RGBFrame>(
new CubicOpenGlFrameCapturer(new CubicEntityRenderer(options), renderInfo, options.getWidth() / 4),
new EquirectangularToARGBProcessor(options.getWidth() / 4),
new EquirectangularToRGBProcessor(options.getWidth() / 4),
consumer
);
}