Separate rendering into its own module

This commit is contained in:
johni0702
2016-06-14 17:01:32 +02:00
parent 65cfdd13ec
commit 25582b6a51
68 changed files with 1822 additions and 2635 deletions

View File

@@ -0,0 +1,12 @@
package com.replaymod.render.processor;
import com.replaymod.render.rendering.Frame;
import com.replaymod.render.rendering.FrameProcessor;
import java.io.IOException;
public abstract class AbstractFrameProcessor<R extends Frame, P extends Frame> implements FrameProcessor<R, P> {
@Override
public void close() throws IOException {
}
}

View File

@@ -0,0 +1,33 @@
package com.replaymod.render.processor;
import com.replaymod.render.frame.CubicOpenGlFrame;
import com.replaymod.render.frame.RGBFrame;
import com.replaymod.render.utils.ByteBufferPool;
import org.lwjgl.util.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 * 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 RGBFrame(rawFrame.getFrameId(), new Dimension(width, height), result);
}
}

View File

@@ -0,0 +1,118 @@
package com.replaymod.render.processor;
import com.replaymod.render.frame.CubicOpenGlFrame;
import com.replaymod.render.frame.RGBFrame;
import com.replaymod.render.utils.ByteBufferPool;
import org.apache.commons.lang3.Validate;
import org.lwjgl.util.Dimension;
import java.nio.ByteBuffer;
import static java.lang.Math.PI;
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;
private static final byte IMAGE_RIGHT = 3;
private static final byte IMAGE_TOP = 4;
private static final byte IMAGE_BOTTOM = 5;
private final int frameSize;
private final int width;
private final int height;
private final byte[][] image;
private final int[][] imageX;
private final int[][] imageY;
public EquirectangularToRGBProcessor(int frameSize) {
this.frameSize = frameSize;
width = frameSize * 4;
height = frameSize * 2;
image = new byte[height][width];
imageX = new int[height][width];
imageY = new int[height][width];
for (int i = 0; i < width; i++) {
double yaw = PI * 2 * i / width;
int piQuarter = 8 * i / width - 4;
byte target;
if (piQuarter < -3) {
target = IMAGE_BACK;
} else if (piQuarter < -1) {
target = IMAGE_LEFT;
} else if (piQuarter < 1) {
target = IMAGE_FRONT;
} else if (piQuarter < 3) {
target = IMAGE_RIGHT;
} else {
target = IMAGE_BACK;
}
double fYaw = (yaw + PI/4) % (PI / 2) - PI/4;
double d = 1 / Math.cos(fYaw);
double gcXN = (Math.tan(fYaw) + 1) / 2;
for (int j = 0; j < height; j++) {
double cXN = gcXN;
byte pt = target;
double pitch = PI * j / height - PI / 2;
double cYN = (Math.tan(pitch) * d + 1) / 2;
if (cYN >= 1) {
double pd = Math.tan(PI/2 - pitch);
cXN = (-Math.sin(yaw) * pd + 1) / 2;
cYN = (Math.cos(yaw) * pd + 1) / 2;
pt = IMAGE_BOTTOM;
}
if (cYN < 0) {
double pd = Math.tan(PI/2 - pitch);
cXN = (Math.sin(yaw) * pd + 1) / 2;
cYN = (Math.cos(yaw) * pd + 1) / 2;
pt = IMAGE_TOP;
}
int imgX = (int) Math.min(frameSize - 1, (cXN * frameSize));
int imgY = (int) Math.min(frameSize - 1, (cYN * frameSize));
image[j][i] = pt;
imageX[j][i] = imgX;
imageY[j][i] = frameSize - imgY - 1; // The OpenGl buffer contains data flipped vertically
}
}
}
@Override
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 * 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[3];
byte[] image;
int[] imageX, imageY;
for (int y = 0; y < height; y++) {
image = this.image[y];
imageX = this.imageX[y];
imageY = this.imageY[y];
for (int x = 0; x < width; x++) {
ByteBuffer source = images[image[x]];
source.position((imageX[x] + imageY[x] * frameSize) * 3);
source.get(pixel);
result.put(pixel);
}
}
result.rewind();
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);
}
}

View File

@@ -0,0 +1,42 @@
package com.replaymod.render.processor;
import com.replaymod.render.frame.OpenGlFrame;
import com.replaymod.render.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

@@ -0,0 +1,27 @@
package com.replaymod.render.processor;
import com.replaymod.render.frame.RGBFrame;
import com.replaymod.render.frame.StereoscopicOpenGlFrame;
import com.replaymod.render.utils.ByteBufferPool;
import org.lwjgl.util.Dimension;
import org.lwjgl.util.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() * 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 RGBFrame(rawFrame.getFrameId(), new Dimension(width * 2, size.getHeight()), result);
}
}