Add PBOs and PBO support for default rendering
This commit is contained in:
@@ -54,7 +54,7 @@ public abstract class OpenGlFrameCapturer<F extends Frame, D extends CaptureData
|
||||
return renderInfo.getFrameSize().getHeight();
|
||||
}
|
||||
|
||||
private Framebuffer frameBuffer() {
|
||||
protected Framebuffer frameBuffer() {
|
||||
if (frameBuffer == null) {
|
||||
frameBuffer = new Framebuffer(getFrameWidth(), getFrameHeight(), true);
|
||||
}
|
||||
@@ -82,6 +82,10 @@ public abstract class OpenGlFrameCapturer<F extends Frame, D extends CaptureData
|
||||
frameBuffer().unbindFramebuffer();
|
||||
popMatrix();
|
||||
|
||||
return captureFrame(frameId);
|
||||
}
|
||||
|
||||
protected OpenGlFrame captureFrame(int frameId) {
|
||||
GL11.glPixelStorei(GL11.GL_PACK_ALIGNMENT, 1);
|
||||
GL11.glPixelStorei(GL11.GL_UNPACK_ALIGNMENT, 1);
|
||||
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
package eu.crushedpixel.replaymod.video.capturer;
|
||||
|
||||
import eu.crushedpixel.replaymod.opengl.PixelBufferObject;
|
||||
import eu.crushedpixel.replaymod.utils.ByteBufferPool;
|
||||
import eu.crushedpixel.replaymod.video.frame.OpenGlFrame;
|
||||
import net.minecraft.client.renderer.OpenGlHelper;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
import org.lwjgl.util.ReadableDimension;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
public class SimplePboOpenGlFrameCapturer extends OpenGlFrameCapturer<OpenGlFrame, CaptureData> {
|
||||
private final int bufferSize;
|
||||
private PixelBufferObject pbo, otherPBO;
|
||||
|
||||
public SimplePboOpenGlFrameCapturer(WorldRenderer<CaptureData> worldRenderer, RenderInfo renderInfo) {
|
||||
super(worldRenderer, renderInfo);
|
||||
|
||||
ReadableDimension size = renderInfo.getFrameSize();
|
||||
bufferSize = size.getHeight() * size.getWidth() * 3;
|
||||
pbo = new PixelBufferObject(bufferSize, PixelBufferObject.Usage.READ);
|
||||
otherPBO = new PixelBufferObject(bufferSize, PixelBufferObject.Usage.READ);
|
||||
}
|
||||
|
||||
private void swapPBOs() {
|
||||
PixelBufferObject old = pbo;
|
||||
pbo = otherPBO;
|
||||
otherPBO = old;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDone() {
|
||||
return framesDone >= renderInfo.getTotalFrames() + 2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public OpenGlFrame process() {
|
||||
OpenGlFrame frame = null;
|
||||
|
||||
if (framesDone > 1) {
|
||||
// Read pbo to memory
|
||||
pbo.bind();
|
||||
ByteBuffer pboBuffer = pbo.mapReadOnly();
|
||||
ByteBuffer buffer = ByteBufferPool.allocate(bufferSize);
|
||||
buffer.put(pboBuffer);
|
||||
buffer.rewind();
|
||||
pbo.unmap();
|
||||
pbo.unbind();
|
||||
frame = new OpenGlFrame(framesDone - 2, frameSize, buffer);
|
||||
}
|
||||
|
||||
if (framesDone < renderInfo.getTotalFrames()) {
|
||||
// Then fill it again
|
||||
renderFrame(framesDone, renderInfo.updateForNextFrame());
|
||||
}
|
||||
|
||||
framesDone++;
|
||||
swapPBOs();
|
||||
return frame;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected OpenGlFrame captureFrame(int frameId) {
|
||||
pbo.bind();
|
||||
|
||||
GL11.glPixelStorei(GL11.GL_PACK_ALIGNMENT, 1);
|
||||
GL11.glPixelStorei(GL11.GL_UNPACK_ALIGNMENT, 1);
|
||||
|
||||
if (OpenGlHelper.isFramebufferEnabled()) {
|
||||
frameBuffer().bindFramebufferTexture();
|
||||
GL11.glGetTexImage(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGB, GL11.GL_UNSIGNED_BYTE, 0);
|
||||
frameBuffer().unbindFramebufferTexture();
|
||||
} else {
|
||||
GL11.glReadPixels(0, 0, getFrameWidth(), getFrameHeight(), GL11.GL_RGB, GL11.GL_UNSIGNED_BYTE, 0);
|
||||
}
|
||||
|
||||
pbo.unbind();
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
pbo.delete();
|
||||
otherPBO.delete();
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package eu.crushedpixel.replaymod.video.rendering;
|
||||
|
||||
import eu.crushedpixel.replaymod.opengl.PixelBufferObject;
|
||||
import eu.crushedpixel.replaymod.settings.RenderOptions;
|
||||
import eu.crushedpixel.replaymod.video.capturer.*;
|
||||
import eu.crushedpixel.replaymod.video.entity.CubicEntityRenderer;
|
||||
@@ -37,11 +38,13 @@ public class Pipelines {
|
||||
|
||||
public static Pipeline<OpenGlFrame, ARGBFrame> newDefaultPipeline(RenderInfo renderInfo, FrameConsumer<ARGBFrame> consumer) {
|
||||
RenderOptions options = renderInfo.getRenderOptions();
|
||||
return new Pipeline<OpenGlFrame, ARGBFrame>(
|
||||
new SimpleOpenGlFrameCapturer(new CustomEntityRenderer<CaptureData>(options), renderInfo),
|
||||
new OpenGlToARGBProcessor(),
|
||||
consumer
|
||||
);
|
||||
FrameCapturer<OpenGlFrame> capturer;
|
||||
if (PixelBufferObject.SUPPORTED) {
|
||||
capturer = new SimplePboOpenGlFrameCapturer(new CustomEntityRenderer<CaptureData>(options), renderInfo);
|
||||
} else {
|
||||
capturer = new SimpleOpenGlFrameCapturer(new CustomEntityRenderer<CaptureData>(options), renderInfo);
|
||||
}
|
||||
return new Pipeline<OpenGlFrame, ARGBFrame>(capturer, new OpenGlToARGBProcessor(), consumer);
|
||||
}
|
||||
|
||||
public static Pipeline<StereoscopicOpenGlFrame, ARGBFrame> newStereoscopicPipeline(RenderInfo renderInfo, FrameConsumer<ARGBFrame> consumer) {
|
||||
|
||||
Reference in New Issue
Block a user