Add depth map export (closes #371)
This commit is contained in:
@@ -1,6 +1,10 @@
|
||||
package com.replaymod.render.capturer;
|
||||
|
||||
import com.replaymod.render.frame.CubicOpenGlFrame;
|
||||
import com.replaymod.render.rendering.Channel;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
public class CubicOpenGlFrameCapturer extends OpenGlFrameCapturer<CubicOpenGlFrame, CubicOpenGlFrameCapturer.Data> {
|
||||
public enum Data implements CaptureData {
|
||||
@@ -25,14 +29,15 @@ public class CubicOpenGlFrameCapturer extends OpenGlFrameCapturer<CubicOpenGlFra
|
||||
}
|
||||
|
||||
@Override
|
||||
public CubicOpenGlFrame process() {
|
||||
public Map<Channel, CubicOpenGlFrame> process() {
|
||||
float partialTicks = renderInfo.updateForNextFrame();
|
||||
int frameId = framesDone++;
|
||||
return new CubicOpenGlFrame(renderFrame(frameId, partialTicks, Data.LEFT),
|
||||
CubicOpenGlFrame frame = new CubicOpenGlFrame(renderFrame(frameId, partialTicks, Data.LEFT),
|
||||
renderFrame(frameId, partialTicks, Data.RIGHT),
|
||||
renderFrame(frameId, partialTicks, Data.FRONT),
|
||||
renderFrame(frameId, partialTicks, Data.BACK),
|
||||
renderFrame(frameId, partialTicks, Data.TOP),
|
||||
renderFrame(frameId, partialTicks, Data.BOTTOM));
|
||||
return Collections.singletonMap(Channel.BRGA, frame);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.replaymod.render.capturer;
|
||||
|
||||
import com.replaymod.render.rendering.Channel;
|
||||
import de.johni0702.minecraft.gui.utils.EventRegistrations;
|
||||
import com.replaymod.render.RenderSettings;
|
||||
import com.replaymod.render.frame.CubicOpenGlFrame;
|
||||
@@ -17,6 +18,8 @@ import net.minecraft.util.Identifier;
|
||||
import static com.mojang.blaze3d.platform.GlStateManager.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.lwjgl.opengl.GL11.GL_COLOR_BUFFER_BIT;
|
||||
import static org.lwjgl.opengl.GL11.GL_DEPTH_BUFFER_BIT;
|
||||
@@ -125,16 +128,22 @@ public class ODSFrameCapturer implements FrameCapturer<ODSOpenGlFrame> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public ODSOpenGlFrame process() {
|
||||
public Map<Channel, ODSOpenGlFrame> process() {
|
||||
bindProgram();
|
||||
leftEyeVariable.set(true);
|
||||
CubicOpenGlFrame leftFrame = left.process();
|
||||
Map<Channel, CubicOpenGlFrame> leftChannels = left.process();
|
||||
leftEyeVariable.set(false);
|
||||
CubicOpenGlFrame rightFrame = right.process();
|
||||
Map<Channel, CubicOpenGlFrame> rightChannels = right.process();
|
||||
unbindProgram();
|
||||
|
||||
if (leftFrame != null && rightFrame != null) {
|
||||
return new ODSOpenGlFrame(leftFrame, rightFrame);
|
||||
if (leftChannels != null && rightChannels != null) {
|
||||
Map<Channel, ODSOpenGlFrame> result = new HashMap<>();
|
||||
for (Channel channel : Channel.values()) {
|
||||
CubicOpenGlFrame leftFrame = leftChannels.get(channel);
|
||||
CubicOpenGlFrame rightFrame = rightChannels.get(channel);
|
||||
result.put(channel, new ODSOpenGlFrame(leftFrame, rightFrame));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package com.replaymod.render.capturer;
|
||||
|
||||
import com.mojang.blaze3d.platform.GlStateManager;
|
||||
import com.replaymod.render.frame.OpenGlFrame;
|
||||
import com.replaymod.render.rendering.Channel;
|
||||
import com.replaymod.render.rendering.Frame;
|
||||
import com.replaymod.render.utils.ByteBufferPool;
|
||||
import com.replaymod.render.utils.PixelBufferObject;
|
||||
@@ -9,17 +11,21 @@ import org.lwjgl.opengl.GL12;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public abstract class PboOpenGlFrameCapturer<F extends Frame, D extends Enum<D> & CaptureData>
|
||||
extends OpenGlFrameCapturer<F, D> {
|
||||
private final boolean withDepth;
|
||||
private final D[] data;
|
||||
private PixelBufferObject pbo, otherPBO;
|
||||
|
||||
public PboOpenGlFrameCapturer(WorldRenderer worldRenderer, RenderInfo renderInfo, Class<D> type, int framePixels) {
|
||||
super(worldRenderer, renderInfo);
|
||||
|
||||
withDepth = renderInfo.getRenderSettings().isDepthMap();
|
||||
data = type.getEnumConstants();
|
||||
int bufferSize = framePixels * 4 * data.length;
|
||||
int bufferSize = framePixels * (4 /* bgra */ + (withDepth ? 4 /* float */ : 0)) * data.length;
|
||||
pbo = new PixelBufferObject(bufferSize, PixelBufferObject.Usage.READ);
|
||||
otherPBO = new PixelBufferObject(bufferSize, PixelBufferObject.Usage.READ);
|
||||
}
|
||||
@@ -37,29 +43,36 @@ public abstract class PboOpenGlFrameCapturer<F extends Frame, D extends Enum<D>
|
||||
return framesDone >= renderInfo.getTotalFrames() + 2;
|
||||
}
|
||||
|
||||
private F readFromPbo(ByteBuffer pboBuffer, int bytesPerPixel) {
|
||||
OpenGlFrame[] frames = new OpenGlFrame[data.length];
|
||||
int frameBufferSize = getFrameWidth() * getFrameHeight() * bytesPerPixel;
|
||||
for (int i = 0; i < frames.length; i++) {
|
||||
ByteBuffer frameBuffer = ByteBufferPool.allocate(frameBufferSize);
|
||||
pboBuffer.limit(pboBuffer.position() + frameBufferSize);
|
||||
frameBuffer.put(pboBuffer);
|
||||
frameBuffer.rewind();
|
||||
frames[i] = new OpenGlFrame(framesDone - 2, frameSize, bytesPerPixel, frameBuffer);
|
||||
}
|
||||
return create(frames);
|
||||
}
|
||||
|
||||
@Override
|
||||
public F process() {
|
||||
F frame = null;
|
||||
public Map<Channel, F> process() {
|
||||
Map<Channel, F> channels = null;
|
||||
|
||||
if (framesDone > 1) {
|
||||
// Read pbo to memory
|
||||
pbo.bind();
|
||||
ByteBuffer pboBuffer = pbo.mapReadOnly();
|
||||
|
||||
OpenGlFrame[] frames = new OpenGlFrame[data.length];
|
||||
int frameBufferSize = getFrameWidth() * getFrameHeight() * 4;
|
||||
for (int i = 0; i < frames.length; i++) {
|
||||
ByteBuffer frameBuffer = ByteBufferPool.allocate(frameBufferSize);
|
||||
pboBuffer.limit(pboBuffer.position() + frameBufferSize);
|
||||
frameBuffer.put(pboBuffer);
|
||||
frameBuffer.rewind();
|
||||
frames[i] = new OpenGlFrame(framesDone - 2, frameSize, 4, frameBuffer);
|
||||
channels = new HashMap<>();
|
||||
channels.put(Channel.BRGA, readFromPbo(pboBuffer, 4));
|
||||
if (withDepth) {
|
||||
channels.put(Channel.DEPTH, readFromPbo(pboBuffer, 4));
|
||||
}
|
||||
|
||||
pbo.unmap();
|
||||
pbo.unbind();
|
||||
|
||||
frame = create(frames);
|
||||
}
|
||||
|
||||
if (framesDone < renderInfo.getTotalFrames()) {
|
||||
@@ -72,7 +85,7 @@ public abstract class PboOpenGlFrameCapturer<F extends Frame, D extends Enum<D>
|
||||
|
||||
framesDone++;
|
||||
swapPBOs();
|
||||
return frame;
|
||||
return channels;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -82,6 +95,10 @@ public abstract class PboOpenGlFrameCapturer<F extends Frame, D extends Enum<D>
|
||||
int offset = captureData.ordinal() * getFrameWidth() * getFrameHeight() * 4;
|
||||
frameBuffer().beginWrite(true);
|
||||
GL11.glReadPixels(0, 0, getFrameWidth(), getFrameHeight(), GL12.GL_BGRA, GL11.GL_UNSIGNED_BYTE, offset);
|
||||
if (withDepth) {
|
||||
offset += data.length * getFrameWidth() * getFrameHeight() * 4;
|
||||
GL11.glReadPixels(0, 0, getFrameWidth(), getFrameHeight(), GL11.GL_DEPTH_COMPONENT, GL11.GL_FLOAT, offset);
|
||||
}
|
||||
frameBuffer().endWrite();
|
||||
|
||||
pbo.unbind();
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
package com.replaymod.render.capturer;
|
||||
|
||||
import com.replaymod.render.frame.OpenGlFrame;
|
||||
import com.replaymod.render.rendering.Channel;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
public class SimpleOpenGlFrameCapturer extends OpenGlFrameCapturer<OpenGlFrame, CaptureData> {
|
||||
|
||||
@@ -9,8 +13,9 @@ public class SimpleOpenGlFrameCapturer extends OpenGlFrameCapturer<OpenGlFrame,
|
||||
}
|
||||
|
||||
@Override
|
||||
public OpenGlFrame process() {
|
||||
public Map<Channel, OpenGlFrame> process() {
|
||||
float partialTicks = renderInfo.updateForNextFrame();
|
||||
return renderFrame(framesDone++, partialTicks);
|
||||
OpenGlFrame frame = renderFrame(framesDone++, partialTicks);
|
||||
return Collections.singletonMap(Channel.BRGA, frame);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,10 @@ package com.replaymod.render.capturer;
|
||||
|
||||
import com.replaymod.render.frame.OpenGlFrame;
|
||||
import com.replaymod.render.frame.StereoscopicOpenGlFrame;
|
||||
import com.replaymod.render.rendering.Channel;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
public class StereoscopicOpenGlFrameCapturer
|
||||
extends OpenGlFrameCapturer<StereoscopicOpenGlFrame, StereoscopicOpenGlFrameCapturer.Data> {
|
||||
@@ -19,11 +23,12 @@ public class StereoscopicOpenGlFrameCapturer
|
||||
}
|
||||
|
||||
@Override
|
||||
public StereoscopicOpenGlFrame process() {
|
||||
public Map<Channel, StereoscopicOpenGlFrame> process() {
|
||||
float partialTicks = renderInfo.updateForNextFrame();
|
||||
int frameId = framesDone++;
|
||||
OpenGlFrame left = renderFrame(frameId, partialTicks, Data.LEFT_EYE);
|
||||
OpenGlFrame right = renderFrame(frameId, partialTicks, Data.RIGHT_EYE);
|
||||
return new StereoscopicOpenGlFrame(left, right);
|
||||
StereoscopicOpenGlFrame frame = new StereoscopicOpenGlFrame(left, right);
|
||||
return Collections.singletonMap(Channel.BRGA, frame);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user