aboutsummaryrefslogtreecommitdiffstats
path: root/ardor3d-lwjgl
diff options
context:
space:
mode:
authorrenanse <[email protected]>2013-02-03 12:10:05 -0600
committerrenanse <[email protected]>2013-02-03 12:10:05 -0600
commite757ccd563c81206aebc586fead0ede52dca2f58 (patch)
tree6cc8d81b246788d6302af801676a2376f350d038 /ardor3d-lwjgl
parentdc29c24ed025144452bade21fbe45ab609c6b854 (diff)
Added detection of MSAA FBO and FBO blit.
Fixed multisample support on LwjglHeadlessCanvas - still needs fixing in FBO texture rendering.
Diffstat (limited to 'ardor3d-lwjgl')
-rw-r--r--ardor3d-lwjgl/src/main/java/com/ardor3d/framework/lwjgl/LwjglHeadlessCanvas.java102
-rw-r--r--ardor3d-lwjgl/src/main/java/com/ardor3d/renderer/lwjgl/LwjglContextCapabilities.java5
2 files changed, 78 insertions, 29 deletions
diff --git a/ardor3d-lwjgl/src/main/java/com/ardor3d/framework/lwjgl/LwjglHeadlessCanvas.java b/ardor3d-lwjgl/src/main/java/com/ardor3d/framework/lwjgl/LwjglHeadlessCanvas.java
index 26f8d78..895bc63 100644
--- a/ardor3d-lwjgl/src/main/java/com/ardor3d/framework/lwjgl/LwjglHeadlessCanvas.java
+++ b/ardor3d-lwjgl/src/main/java/com/ardor3d/framework/lwjgl/LwjglHeadlessCanvas.java
@@ -16,6 +16,8 @@ import java.nio.IntBuffer;
import org.lwjgl.LWJGLException;
import org.lwjgl.opengl.ARBMultisample;
+import org.lwjgl.opengl.EXTFramebufferBlit;
+import org.lwjgl.opengl.EXTFramebufferMultisample;
import org.lwjgl.opengl.EXTFramebufferObject;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL12;
@@ -36,7 +38,6 @@ import com.ardor3d.renderer.lwjgl.LwjglContextCapabilities;
import com.ardor3d.renderer.lwjgl.LwjglRenderer;
import com.ardor3d.renderer.lwjgl.LwjglTextureRenderer;
import com.ardor3d.util.Ardor3dException;
-import com.ardor3d.util.Constants;
import com.ardor3d.util.geom.BufferUtils;
/**
@@ -57,6 +58,8 @@ public class LwjglHeadlessCanvas {
protected Camera _camera;
protected int _fboID, _depthRBID, _colorRBID;
+ protected int _msfboID, _msdepthRBID, _mscolorRBID;
+ protected boolean _useMSAA = false;
protected IntBuffer _data;
protected Pbuffer _buff;
@@ -82,19 +85,11 @@ public class LwjglHeadlessCanvas {
try {
// Create a Pbuffer so we can have a valid gl context to work with
final PixelFormat format = new PixelFormat(_settings.getAlphaBits(), _settings.getDepthBits(),
- _settings.getStencilBits()).withSamples(_settings.getSamples());
+ _settings.getStencilBits());
_buff = new Pbuffer(1, 1, format, null);
_buff.makeCurrent();
} catch (final LWJGLException ex) {
- try {
- // try again without samples
- final PixelFormat format = new PixelFormat(_settings.getAlphaBits(), _settings.getDepthBits(),
- _settings.getStencilBits());
- _buff = new Pbuffer(1, 1, format, null);
- _buff.makeCurrent();
- } catch (final LWJGLException ex2) {
- ex2.printStackTrace();
- }
+ ex.printStackTrace();
}
// Set up our Ardor3D context and capabilities objects
@@ -105,6 +100,10 @@ public class LwjglHeadlessCanvas {
throw new Ardor3dException("Headless requires FBO support.");
}
+ if (caps.isFBOMultisampleSupported() && caps.isFBOBlitSupported() && _settings.getSamples() > 0) {
+ _useMSAA = true;
+ }
+
// Init our FBO.
final IntBuffer buffer = BufferUtils.createIntBuffer(1);
EXTFramebufferObject.glGenFramebuffersEXT(buffer); // generate id
@@ -113,12 +112,13 @@ public class LwjglHeadlessCanvas {
_fboID = buffer.get(0);
EXTFramebufferObject.glBindFramebufferEXT(EXTFramebufferObject.GL_FRAMEBUFFER_EXT, _fboID);
- // initial our color renderbuffer
+ // initialize our color renderbuffer
EXTFramebufferObject.glGenRenderbuffersEXT(buffer); // generate id
_colorRBID = buffer.get(0);
EXTFramebufferObject.glBindRenderbufferEXT(EXTFramebufferObject.GL_RENDERBUFFER_EXT, _colorRBID);
EXTFramebufferObject.glRenderbufferStorageEXT(EXTFramebufferObject.GL_RENDERBUFFER_EXT, GL11.GL_RGBA, width,
height);
+
// Attach color renderbuffer to framebuffer
EXTFramebufferObject.glFramebufferRenderbufferEXT(EXTFramebufferObject.GL_FRAMEBUFFER_EXT,
EXTFramebufferObject.GL_COLOR_ATTACHMENT0_EXT, EXTFramebufferObject.GL_RENDERBUFFER_EXT, _colorRBID);
@@ -129,6 +129,7 @@ public class LwjglHeadlessCanvas {
EXTFramebufferObject.glBindRenderbufferEXT(EXTFramebufferObject.GL_RENDERBUFFER_EXT, _depthRBID);
EXTFramebufferObject.glRenderbufferStorageEXT(EXTFramebufferObject.GL_RENDERBUFFER_EXT,
GL11.GL_DEPTH_COMPONENT, width, height);
+
// Attach depth renderbuffer to framebuffer
EXTFramebufferObject.glFramebufferRenderbufferEXT(EXTFramebufferObject.GL_FRAMEBUFFER_EXT,
EXTFramebufferObject.GL_DEPTH_ATTACHMENT_EXT, EXTFramebufferObject.GL_RENDERBUFFER_EXT, _depthRBID);
@@ -136,6 +137,47 @@ public class LwjglHeadlessCanvas {
// Check FBO complete
LwjglTextureRenderer.checkFBOComplete(_fboID);
+ // Now do it all again for multisample, if requested and supported
+ if (_useMSAA) {
+
+ // Init our ms FBO.
+ EXTFramebufferObject.glGenFramebuffersEXT(buffer); // generate id
+
+ // Bind the ms FBO
+ _msfboID = buffer.get(0);
+ EXTFramebufferObject.glBindFramebufferEXT(EXTFramebufferObject.GL_FRAMEBUFFER_EXT, _msfboID);
+
+ // initialize our ms color renderbuffer
+ EXTFramebufferObject.glGenRenderbuffersEXT(buffer); // generate id
+ _mscolorRBID = buffer.get(0);
+ EXTFramebufferObject.glBindRenderbufferEXT(EXTFramebufferObject.GL_RENDERBUFFER_EXT, _mscolorRBID);
+ EXTFramebufferMultisample.glRenderbufferStorageMultisampleEXT(EXTFramebufferObject.GL_RENDERBUFFER_EXT,
+ _settings.getSamples(), GL11.GL_RGBA, width, height);
+
+ // Attach ms color renderbuffer to ms framebuffer
+ EXTFramebufferObject.glFramebufferRenderbufferEXT(EXTFramebufferObject.GL_FRAMEBUFFER_EXT,
+ EXTFramebufferObject.GL_COLOR_ATTACHMENT0_EXT, EXTFramebufferObject.GL_RENDERBUFFER_EXT,
+ _mscolorRBID);
+
+ // initialize our ms depth renderbuffer
+ EXTFramebufferObject.glGenRenderbuffersEXT(buffer); // generate id
+ _msdepthRBID = buffer.get(0);
+ EXTFramebufferObject.glBindRenderbufferEXT(EXTFramebufferObject.GL_RENDERBUFFER_EXT, _msdepthRBID);
+ EXTFramebufferMultisample.glRenderbufferStorageMultisampleEXT(EXTFramebufferObject.GL_RENDERBUFFER_EXT,
+ _settings.getSamples(), GL11.GL_DEPTH_COMPONENT, width, height);
+
+ // Attach ms depth renderbuffer to ms framebuffer
+ EXTFramebufferObject.glFramebufferRenderbufferEXT(EXTFramebufferObject.GL_FRAMEBUFFER_EXT,
+ EXTFramebufferObject.GL_DEPTH_ATTACHMENT_EXT, EXTFramebufferObject.GL_RENDERBUFFER_EXT,
+ _msdepthRBID);
+
+ // Check MS FBO complete
+ LwjglTextureRenderer.checkFBOComplete(_msfboID);
+
+ // enable multisample
+ GL11.glEnable(ARBMultisample.GL_MULTISAMPLE_ARB);
+ }
+
// Setup our data buffer for storing rendered image data.
_data = ByteBuffer.allocateDirect(width * height * 4).order(ByteOrder.LITTLE_ENDIAN).asIntBuffer();
@@ -143,11 +185,6 @@ public class LwjglHeadlessCanvas {
ContextManager.addContext(this, currentContext);
ContextManager.switchContext(this);
- // Turn on multisample if requested...
- if (_settings.getSamples() != 0 && caps.isMultisampleSupported()) {
- GL11.glEnable(ARBMultisample.GL_MULTISAMPLE_ARB);
- }
-
// Setup a default bg color.
_renderer.setBackgroundColor(ColorRGBA.BLACK);
@@ -163,17 +200,14 @@ public class LwjglHeadlessCanvas {
final Vector3 dir = new Vector3(0.0f, 0f, -1.0f);
_camera.setFrame(loc, left, up, dir);
- if (Constants.useMultipleContexts) {
- // release our FBO until used.
- EXTFramebufferObject.glBindFramebufferEXT(EXTFramebufferObject.GL_FRAMEBUFFER_EXT, 0);
- }
+ // release our FBO(s) until used.
+ EXTFramebufferObject.glBindFramebufferEXT(EXTFramebufferObject.GL_FRAMEBUFFER_EXT, 0);
}
public void draw() {
- if (Constants.useMultipleContexts) {
- // activate FBO
- EXTFramebufferObject.glBindFramebufferEXT(EXTFramebufferObject.GL_FRAMEBUFFER_EXT, _fboID);
- }
+ // bind correct fbo
+ EXTFramebufferObject
+ .glBindFramebufferEXT(EXTFramebufferObject.GL_FRAMEBUFFER_EXT, _useMSAA ? _msfboID : _fboID);
// Make sure this OpenGL context is current.
ContextManager.switchContext(this);
@@ -197,15 +231,25 @@ public class LwjglHeadlessCanvas {
_scene.renderUnto(_renderer);
_renderer.flushFrame(false);
+ // if we're multisampled, we need to blit to a non-multisampled fbo first
+ if (_useMSAA) {
+ EXTFramebufferObject.glBindFramebufferEXT(EXTFramebufferBlit.GL_DRAW_FRAMEBUFFER_EXT, _fboID);
+ EXTFramebufferObject.glBindFramebufferEXT(EXTFramebufferBlit.GL_READ_FRAMEBUFFER_EXT, _msfboID);
+ EXTFramebufferBlit.glBlitFramebufferEXT(0, 0, _settings.getWidth(), _settings.getHeight(), 0, 0,
+ _settings.getWidth(), _settings.getHeight(), GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT
+ | GL11.GL_STENCIL_BUFFER_BIT, GL11.GL_NEAREST);
+
+ // get ready to read non-msaa fbo
+ EXTFramebufferObject.glBindFramebufferEXT(EXTFramebufferObject.GL_FRAMEBUFFER_EXT, _fboID);
+ }
+
// read data from our color buffer
_data.rewind();
GL11.glReadBuffer(EXTFramebufferObject.GL_COLOR_ATTACHMENT0_EXT);
GL11.glReadPixels(0, 0, _settings.getWidth(), _settings.getHeight(), GL12.GL_BGRA, GL11.GL_UNSIGNED_BYTE, _data);
- if (Constants.useMultipleContexts) {
- // release our FBO.
- EXTFramebufferObject.glBindFramebufferEXT(EXTFramebufferObject.GL_FRAMEBUFFER_EXT, 0);
- }
+ // release our FBO.
+ EXTFramebufferObject.glBindFramebufferEXT(EXTFramebufferObject.GL_FRAMEBUFFER_EXT, 0);
}
public void releaseContext() throws LWJGLException {
diff --git a/ardor3d-lwjgl/src/main/java/com/ardor3d/renderer/lwjgl/LwjglContextCapabilities.java b/ardor3d-lwjgl/src/main/java/com/ardor3d/renderer/lwjgl/LwjglContextCapabilities.java
index af52d28..08f6e32 100644
--- a/ardor3d-lwjgl/src/main/java/com/ardor3d/renderer/lwjgl/LwjglContextCapabilities.java
+++ b/ardor3d-lwjgl/src/main/java/com/ardor3d/renderer/lwjgl/LwjglContextCapabilities.java
@@ -80,7 +80,12 @@ public class LwjglContextCapabilities extends ContextCapabilities {
// FBO
_fboSupported = caps.GL_EXT_framebuffer_object;
+ System.err.println(caps.GL_EXT_framebuffer_multisample);
if (_fboSupported) {
+
+ _supportsFBOMultisample = caps.GL_EXT_framebuffer_multisample;
+ _supportsFBOBlit = caps.GL_EXT_framebuffer_blit;
+
if (caps.GL_ARB_draw_buffers) {
GL11.glGetInteger(EXTFramebufferObject.GL_MAX_COLOR_ATTACHMENTS_EXT, buf);
_maxFBOColorAttachments = buf.get(0);