* Better checking for MRT in renderer (first against max color attachments then against draw buffers)
* Now uses only OpenGL2 draw buffers instead of relying on GL_ARB_draw_buffers existing * copyFrameBuffer() was non-functional when used against the main framebuffer because the width/height were set to zero erroneously, now it uses the current viewport parameters. * Added TestRenderToCubemap to demonstrate render to cubemap functionality, it also uses MRT to render to all the cube sides git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@9378 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
This commit is contained in:
parent
fba447dc60
commit
cac820803b
@ -355,12 +355,19 @@ public class LwjglRenderer implements Renderer {
|
||||
logger.log(Level.FINER, "Texture Multisample Depth Samples: {0}", maxDepthTexSamples);
|
||||
}
|
||||
|
||||
if (ctxCaps.GL_ARB_draw_buffers) {
|
||||
glGetInteger(GL_MAX_DRAW_BUFFERS, intBuf16);
|
||||
maxMRTFBOAttachs = intBuf16.get(0);
|
||||
if (maxMRTFBOAttachs > 1) {
|
||||
caps.add(Caps.FrameBufferMRT);
|
||||
glGetInteger(ARBDrawBuffers.GL_MAX_DRAW_BUFFERS_ARB, intBuf16);
|
||||
maxMRTFBOAttachs = intBuf16.get(0);
|
||||
logger.log(Level.FINER, "FBO Max MRT renderbuffers: {0}", maxMRTFBOAttachs);
|
||||
}
|
||||
|
||||
// if (ctxCaps.GL_ARB_draw_buffers) {
|
||||
// caps.add(Caps.FrameBufferMRT);
|
||||
// glGetInteger(ARBDrawBuffers.GL_MAX_DRAW_BUFFERS_ARB, intBuf16);
|
||||
// maxMRTFBOAttachs = intBuf16.get(0);
|
||||
// logger.log(Level.FINER, "FBO Max MRT renderbuffers: {0}", maxMRTFBOAttachs);
|
||||
//}
|
||||
}
|
||||
|
||||
if (ctxCaps.GL_ARB_multisample) {
|
||||
@ -1175,11 +1182,26 @@ public class LwjglRenderer implements Renderer {
|
||||
|
||||
public void copyFrameBuffer(FrameBuffer src, FrameBuffer dst, boolean copyDepth) {
|
||||
if (GLContext.getCapabilities().GL_EXT_framebuffer_blit) {
|
||||
int srcX = 0;
|
||||
int srcY = 0;
|
||||
int srcW = 0;
|
||||
int srcH = 0;
|
||||
|
||||
int dstX = 0;
|
||||
int dstY = 0;
|
||||
int dstW = 0;
|
||||
int dstH = 0;
|
||||
|
||||
int prevFBO = context.boundFBO;
|
||||
|
||||
if (mainFbOverride != null) {
|
||||
if (src == null) {
|
||||
src = mainFbOverride;
|
||||
}
|
||||
if (dst == null) {
|
||||
dst = mainFbOverride;
|
||||
}
|
||||
}
|
||||
|
||||
if (src != null && src.isUpdateNeeded()) {
|
||||
updateFrameBuffer(src);
|
||||
@ -1191,8 +1213,10 @@ public class LwjglRenderer implements Renderer {
|
||||
|
||||
if (src == null) {
|
||||
glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, 0);
|
||||
// srcW = viewWidth;
|
||||
// srcH = viewHeight;
|
||||
srcX = vpX;
|
||||
srcY = vpY;
|
||||
srcW = vpW;
|
||||
srcH = vpH;
|
||||
} else {
|
||||
glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, src.getId());
|
||||
srcW = src.getWidth();
|
||||
@ -1200,20 +1224,22 @@ public class LwjglRenderer implements Renderer {
|
||||
}
|
||||
if (dst == null) {
|
||||
glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, 0);
|
||||
// dstW = viewWidth;
|
||||
// dstH = viewHeight;
|
||||
dstX = vpX;
|
||||
dstY = vpY;
|
||||
dstW = vpW - 1;
|
||||
dstH = vpH - 1;
|
||||
} else {
|
||||
glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, dst.getId());
|
||||
dstW = dst.getWidth();
|
||||
dstH = dst.getHeight();
|
||||
dstW = dst.getWidth() - 1;
|
||||
dstH = dst.getHeight() - 1;
|
||||
}
|
||||
int mask = GL_COLOR_BUFFER_BIT;
|
||||
if (copyDepth) {
|
||||
mask |= GL_DEPTH_BUFFER_BIT;
|
||||
}
|
||||
glBlitFramebufferEXT(0, 0, srcW, srcH,
|
||||
0, 0, dstW, dstH, mask,
|
||||
GL_NEAREST);
|
||||
0, 0, dstW, dstH, mask,
|
||||
GL_NEAREST);
|
||||
|
||||
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, prevFBO);
|
||||
@ -1563,11 +1589,16 @@ public class LwjglRenderer implements Renderer {
|
||||
context.boundReadBuf = -2;
|
||||
}
|
||||
} else {
|
||||
if (fb.getNumColorBuffers() > maxFBOAttachs) {
|
||||
throw new RendererException("Framebuffer has more color "
|
||||
+ "attachments than are supported"
|
||||
+ " by the video hardware!");
|
||||
}
|
||||
if (fb.isMultiTarget()) {
|
||||
if (fb.getNumColorBuffers() > maxMRTFBOAttachs) {
|
||||
throw new RendererException("Framebuffer has more"
|
||||
+ " targets than are supported"
|
||||
+ " on the system!");
|
||||
+ " multi targets than are supported"
|
||||
+ " by the video hardware!");
|
||||
}
|
||||
|
||||
if (context.boundDrawBuf != 100 + fb.getNumColorBuffers()) {
|
||||
|
132
engine/src/test/jme3test/post/TestRenderToCubemap.java
Normal file
132
engine/src/test/jme3test/post/TestRenderToCubemap.java
Normal file
@ -0,0 +1,132 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2012 jMonkeyEngine
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package jme3test.post;
|
||||
|
||||
import com.jme3.app.SimpleApplication;
|
||||
import com.jme3.material.Material;
|
||||
import com.jme3.math.ColorRGBA;
|
||||
import com.jme3.math.FastMath;
|
||||
import com.jme3.math.Quaternion;
|
||||
import com.jme3.math.Vector3f;
|
||||
import com.jme3.renderer.Camera;
|
||||
import com.jme3.renderer.ViewPort;
|
||||
import com.jme3.scene.Geometry;
|
||||
import com.jme3.scene.shape.Box;
|
||||
import com.jme3.texture.FrameBuffer;
|
||||
import com.jme3.texture.Image.Format;
|
||||
import com.jme3.texture.Texture;
|
||||
import com.jme3.texture.TextureCubeMap;
|
||||
import com.jme3.util.SkyFactory;
|
||||
|
||||
/**
|
||||
* Renders a rotating box to a cubemap texture, then applies the cubemap
|
||||
* texture as a sky.
|
||||
*/
|
||||
public class TestRenderToCubemap extends SimpleApplication {
|
||||
|
||||
private Geometry offBox;
|
||||
private float angle = 0;
|
||||
private ViewPort offView;
|
||||
|
||||
public static void main(String[] args){
|
||||
TestRenderToCubemap app = new TestRenderToCubemap();
|
||||
app.start();
|
||||
}
|
||||
|
||||
public Texture setupOffscreenView(){
|
||||
Camera offCamera = new Camera(512, 512);
|
||||
|
||||
offView = renderManager.createPreView("Offscreen View", offCamera);
|
||||
offView.setClearFlags(true, true, true);
|
||||
offView.setBackgroundColor(ColorRGBA.DarkGray);
|
||||
|
||||
// create offscreen framebuffer
|
||||
FrameBuffer offBuffer = new FrameBuffer(512, 512, 1);
|
||||
|
||||
//setup framebuffer's cam
|
||||
offCamera.setFrustumPerspective(45f, 1f, 1f, 1000f);
|
||||
offCamera.setLocation(new Vector3f(0f, 0f, -5f));
|
||||
offCamera.lookAt(new Vector3f(0f, 0f, 0f), Vector3f.UNIT_Y);
|
||||
|
||||
//setup framebuffer's texture
|
||||
TextureCubeMap offTex = new TextureCubeMap(512, 512, Format.RGBA8);
|
||||
offTex.setMinFilter(Texture.MinFilter.Trilinear);
|
||||
offTex.setMagFilter(Texture.MagFilter.Bilinear);
|
||||
|
||||
//setup framebuffer to use texture
|
||||
offBuffer.setDepthBuffer(Format.Depth);
|
||||
offBuffer.setMultiTarget(true);
|
||||
offBuffer.addColorTexture(offTex, TextureCubeMap.Face.NegativeX);
|
||||
offBuffer.addColorTexture(offTex, TextureCubeMap.Face.PositiveX);
|
||||
offBuffer.addColorTexture(offTex, TextureCubeMap.Face.NegativeY);
|
||||
offBuffer.addColorTexture(offTex, TextureCubeMap.Face.PositiveY);
|
||||
offBuffer.addColorTexture(offTex, TextureCubeMap.Face.NegativeZ);
|
||||
offBuffer.addColorTexture(offTex, TextureCubeMap.Face.PositiveZ);
|
||||
|
||||
//set viewport to render to offscreen framebuffer
|
||||
offView.setOutputFrameBuffer(offBuffer);
|
||||
|
||||
// setup framebuffer's scene
|
||||
Box boxMesh = new Box(Vector3f.ZERO, 1,1,1);
|
||||
Material material = assetManager.loadMaterial("Interface/Logo/Logo.j3m");
|
||||
offBox = new Geometry("box", boxMesh);
|
||||
offBox.setMaterial(material);
|
||||
|
||||
// attach the scene to the viewport to be rendered
|
||||
offView.attachScene(offBox);
|
||||
|
||||
return offTex;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void simpleInitApp() {
|
||||
cam.setLocation(new Vector3f(3, 3, 3));
|
||||
cam.lookAt(Vector3f.ZERO, Vector3f.UNIT_Y);
|
||||
|
||||
Texture offTex = setupOffscreenView();
|
||||
rootNode.attachChild(SkyFactory.createSky(assetManager, offTex, false));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void simpleUpdate(float tpf){
|
||||
Quaternion q = new Quaternion();
|
||||
|
||||
angle += tpf;
|
||||
angle %= FastMath.TWO_PI;
|
||||
q.fromAngles(angle, 0, angle);
|
||||
|
||||
offBox.setLocalRotation(q);
|
||||
offBox.updateLogicalState(tpf);
|
||||
offBox.updateGeometricState();
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user