Ok, so I’m trying to use the Picture class, right now just focusing on the video frames without the z-buffer. For now I’m generating random RGB values for the video frames, which would cause a “color TV snow” look if displayed, however I have been unable to render it. What am I missing? Here is my code (the commented code in postQueue() is other code I used to try to get it to work):
public class MixedRenderer implements SceneProcessor {
private ByteBuffer frameData;
/** Picture which shows the current video frame. */
private Picture picture;
/** Scene Node that video frame Picture is attached to. */
private Node videoFrameNode;
/** Pre-view ViewPort for displaying video in the background. */
private ViewPort videoViewPort;
/** Display width/height. */
private int width;
private int height;
private AssetManager assetManager;
/** Texture which holds the video frame. */
private Texture2D videoTexture;
private RenderManager rm;
private ViewPort vp;
/** Camera that views the video frame; does not move with scene camera. */
private Camera videoCam;
/** Image which holds the current video frame. */
private Image frameImage;
/** Video frame pixel data. */
byte[] bytes;
private boolean initialized = false;
public MixedRenderer(AssetManager assetManager, int width, int height) {
this.width = width;
this.height = height;
this.assetManager = assetManager;
}
@Override
public void initialize(RenderManager rm, ViewPort vp) {
this.rm = rm;
this.vp = vp;
this.videoCam = new Camera(width, height);
picture = new Picture("Video Frame", false);
picture.setPosition(0, 0);
picture.setWidth(320);
picture.setHeight(240);
videoFrameNode = new Node("Video Node");
videoFrameNode.setQueueBucket(Bucket.Sky);
videoFrameNode.setCullHint(CullHint.Never);
videoFrameNode.attachChild(picture);
videoViewPort = rm.createPreView("Video View", videoCam);
videoViewPort.setClearEnabled(true);
videoViewPort.setBackgroundColor(ColorRGBA.Blue);
videoViewPort.attachScene(videoFrameNode);
bytes = new byte[320*240*4];
frameData = ByteBuffer.allocateDirect(bytes.length);
frameImage = new Image(Image.Format.RGBA8, 320, 240, frameData);
videoTexture = new Texture2D(320, 240, Image.Format.RGBA8);
initialized = true;
}
@Override
public void reshape(ViewPort vp, int w, int h) {
}
@Override
public boolean isInitialized() {
return initialized;
}
@Override
public void preFrame(float tpf) {
videoFrameNode.updateLogicalState(tpf);
videoFrameNode.updateGeometricState();
}
@Override
public void postQueue(RenderQueue rq) {
// videoCam.setProjectionMatrix(null);
Camera prevCam = rm.getCurrentCamera();
rm.setCamera(videoCam, false);
// rm.getRenderer().clearBuffers(true, true, true);
// rm.getRenderer().setDepthRange(1, 1);
for (int i = 0; i < bytes.length-3; i += 4) {
bytes[i] = (byte) (Math.random() * 255 - 128);
bytes[i+1] = (byte) (Math.random() * 255 - 128);
bytes[i+2] = (byte) (Math.random() * 255 - 128);
bytes[i+3] = (byte) (Math.random() * 255 - 128);
}
frameData.put(bytes);
frameImage.setData(frameData); // needed?
videoTexture.setImage(frameImage); // needed?
picture.setTexture(assetManager, videoTexture, false);
vp.getQueue().renderQueue(Bucket.Sky, rm, videoCam);
rm.setCamera(prevCam, false);
}
public void postFrame(FrameBuffer out) {
}
public void cleanup() {
}
}
And in the main class which extends SimpleApplication we have:
public void simpleInitApp() {
. . .
mixedRenderer = new MixedRenderer(assetManager, settings.getWidth(), settings.getHeight());
viewPort.addProcessor(mixedRenderer);
}