I would like to post code, but my code is huge. Not possible to pull it out of the project.
I would have to write a simple application to be able to post it.
In the picture above. That is showing two offscreen buffer renders. I attach 2 spatial (texture) geometries to SimpleApplication.guiNode.
The gui one is on top, the 3d is below. From the picture, you can see the play area, that is the 3d scene rendered to a texture and that texture is assigned to a “Box” (geometry) and attached to guiNode.
The gui screen is attach as startup and stays attach at all time. The 3d texture is only attached when the player clicks on start, and when the game is over it is detached.
Inside Main.cpp (which is the SimpleApplication).
public void simpleUpdate(float tpf)
{
for (FrameBufferItem frameBuffer : offViewBuffers)
{
if (frameBuffer.isEnabled())
frameBuffer.simpleUpdate(tpf);
}
renderTo3DFrameBuffer.simpleUpdate(tpf);
renderToGUIFrameBuffer.simpleUpdate(tpf);
Ignore the first part where it talks about offViewBuffers. That is completely something different. That is for Gui area that need scroll bars with clipping. So is can display text that is clipped on left/right or top/down and have scroll bars. Since JME does not have the ability to easy define an area and clip it like OpenGL offers, due to structure.
The renderT03dFrameBufrfer and renderToGuiFrameBuffer, do what I’m talking about.
public void simpleUpdate(float tpf)
{
//We need to make sure the game Node gets updated, since it is not
//tied to guiNode or rootNode. We have to call it manually.
List<Spatial> scenes = offView.getScenes();
for (Spatial scene : scenes) {
scene.updateLogicalState(tpf);
scene.updateGeometricState();
}
}
Inside those classes (same class), they handle rendering the scene to the texture.
When the player plays for the first time, everything works. Say play dies and goes back to main menu and then clicks play again. Then the 3d texture is never updated and the texture remains unchange from the last frame from the first game. No matter how many times the player quits and tries playing again. Has to shutdown the game and relaunch it.
The definition of the off screen buffer is as follows:
public Texture setupOffscreenViewPort(RenderManager renderManager, Camera camera, Texture texture)
{
offCamera = camera.clone();
float aspect = (float) offCamera.getWidth() / offCamera.getHeight();
// setup framebuffer's cam
offCamera.resize(width, height, true);
offCamera.setFrustumPerspective(60, aspect, 1, 1000);
offView = renderManager.createPreView(name + " 3D Offscreen View", offCamera);
if (texture != null)
offView.setClearFlags(false, true, true);
else
offView.setClearFlags(true, true, true);
offView.setBackgroundColor(new ColorRGBA(0.0f, 0.0f, 0.0f, 0.0f));
// create offscreen framebuffer
FrameBuffer offBuffer = new FrameBuffer(width, height, 1);
// setup framebuffer's texture
Texture2D offTex = new Texture2D(width, height, Format.RGBA8);
offTex.setMinFilter(Texture.MinFilter.Trilinear);
offTex.setMagFilter(Texture.MagFilter.Bilinear);
if (texture != null)
{
offTex.setImage(texture.getImage());
}
// setup framebuffer to use texture
offBuffer.setDepthBuffer(Format.Depth);
FrameBufferTextureTarget buffTar = FrameBufferTarget.newTarget((Texture) offTex);
// FrameBufferTextureTarget buffTar = FrameBufferTarget.newTarget(background);
// Texture texture = buffTar.getTexture();
if (texture != null)
texture.getImage().setFormat(Format.RGBA8);
offBuffer.addColorTarget(buffTar);
// set viewport to render to offscreen framebuffer
offView.setOutputFrameBuffer(offBuffer);
// fbNode.setQueueBucket(Bucket.Gui);
// attach the scene to the viewport to be rendered
foregroundNode.setCullHint(CullHint.Never);
offView.attachScene(foregroundNode);
return offTex;
}
public void simpleUpdate(float tpf)
{
// We need to make sure the game Node gets updated, since it is not
// tied to guiNode or rootNode. We have to call it manually.
// offView.setClearFlags(true, true, true);
List<Spatial> scenes = offView.getScenes();
for (Spatial scene : scenes)
{
scene.updateLogicalState(tpf);
scene.updateGeometricState();
}
}
It is basically taken from the example from JME.