aboutsummaryrefslogtreecommitdiffstats
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
parentdc29c24ed025144452bade21fbe45ab609c6b854 (diff)
Added detection of MSAA FBO and FBO blit.
Fixed multisample support on LwjglHeadlessCanvas - still needs fixing in FBO texture rendering.
-rw-r--r--ardor3d-core/src/main/java/com/ardor3d/renderer/ContextCapabilities.java16
-rw-r--r--ardor3d-examples/src/main/java/com/ardor3d/example/basic/LwjglHeadlessExample.java3
-rw-r--r--ardor3d-jogl/src/main/java/com/ardor3d/renderer/jogl/JoglContextCapabilities.java25
-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
5 files changed, 111 insertions, 40 deletions
diff --git a/ardor3d-core/src/main/java/com/ardor3d/renderer/ContextCapabilities.java b/ardor3d-core/src/main/java/com/ardor3d/renderer/ContextCapabilities.java
index f2ac794..3e8d55c 100644
--- a/ardor3d-core/src/main/java/com/ardor3d/renderer/ContextCapabilities.java
+++ b/ardor3d-core/src/main/java/com/ardor3d/renderer/ContextCapabilities.java
@@ -43,6 +43,8 @@ public class ContextCapabilities {
protected boolean _pbufferSupported = false;
protected boolean _fboSupported = false;
+ protected boolean _supportsFBOMultisample = false;
+ protected boolean _supportsFBOBlit = false;
protected int _maxFBOColorAttachments = 1;
protected int _maxFBOSamples = 0;
@@ -227,6 +229,20 @@ public class ContextCapabilities {
}
/**
+ * @return true if we support fbo multisampling (antialiasing)
+ */
+ public boolean isFBOMultisampleSupported() {
+ return _supportsFBOMultisample;
+ }
+
+ /**
+ * @return true if we support fbo blitting
+ */
+ public boolean isFBOBlitSupported() {
+ return _supportsFBOBlit;
+ }
+
+ /**
* @return true if we support setting a constant color for use with *Constant* type BlendFunctions.
*/
public boolean isConstantBlendColorSupported() {
diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/basic/LwjglHeadlessExample.java b/ardor3d-examples/src/main/java/com/ardor3d/example/basic/LwjglHeadlessExample.java
index c0f147f..516b46a 100644
--- a/ardor3d-examples/src/main/java/com/ardor3d/example/basic/LwjglHeadlessExample.java
+++ b/ardor3d-examples/src/main/java/com/ardor3d/example/basic/LwjglHeadlessExample.java
@@ -110,7 +110,8 @@ public class LwjglHeadlessExample implements Scene {
*/
public LwjglHeadlessExample() {
// Setup our headless canvas for rendering.
- settings = new DisplaySettings(800, 600, 0, 0, false);
+ // settings = new DisplaySettings(800, 600, 0, 0, 0, 16, 0, 4, false, false); // use this to try MSAA
+ settings = new DisplaySettings(800, 600, 0, 0, 0, 16, 0, 0, false, false);
canvas = new LwjglHeadlessCanvas(settings, this);
canvas.getRenderer().setBackgroundColor(ColorRGBA.BLACK_NO_ALPHA);
diff --git a/ardor3d-jogl/src/main/java/com/ardor3d/renderer/jogl/JoglContextCapabilities.java b/ardor3d-jogl/src/main/java/com/ardor3d/renderer/jogl/JoglContextCapabilities.java
index 7bc4e01..bfb39bd 100644
--- a/ardor3d-jogl/src/main/java/com/ardor3d/renderer/jogl/JoglContextCapabilities.java
+++ b/ardor3d-jogl/src/main/java/com/ardor3d/renderer/jogl/JoglContextCapabilities.java
@@ -74,10 +74,11 @@ public class JoglContextCapabilities extends ContextCapabilities {
_geometryShader4Supported = gl.isExtensionAvailable("GL_ARB_geometry_shader4") && _glslSupported;
- _geometryInstancingSupported = gl.isExtensionAvailable("GL_EXT_draw_instanced") || gl.isExtensionAvailable("GL_VERSION_3_0");
-
+ _geometryInstancingSupported = gl.isExtensionAvailable("GL_EXT_draw_instanced")
+ || gl.isExtensionAvailable("GL_VERSION_3_0");
+
_tessellationShadersSupported = gl.isExtensionAvailable("GL_ARB_tessellation_shader") && _glslSupported;
-
+
if (_glslSupported) {
gl.glGetIntegerv(GL2.GL_MAX_VERTEX_ATTRIBS_ARB, buf);
_maxGLSLVertexAttribs = buf.get(0);
@@ -89,6 +90,10 @@ public class JoglContextCapabilities extends ContextCapabilities {
// FBO
_fboSupported = gl.isExtensionAvailable("GL_EXT_framebuffer_object");
if (_fboSupported) {
+
+ _supportsFBOMultisample = gl.isExtensionAvailable("GL_EXT_framebuffer_multisample");
+ _supportsFBOBlit = gl.isExtensionAvailable("GL_EXT_framebuffer_blit");
+
if (gl.isExtensionAvailable("GL_ARB_draw_buffers")) {
gl.glGetIntegerv(GL2ES2.GL_MAX_COLOR_ATTACHMENTS, buf);
_maxFBOColorAttachments = buf.get(0);
@@ -122,11 +127,11 @@ public class JoglContextCapabilities extends ContextCapabilities {
// Check for support of multitextures.
_supportsMultiTexture = gl.isExtensionAvailable("GL_ARB_multitexture");
- // Support for texture formats
- _supportsFloatTextures = gl.isExtensionAvailable("GL_ARB_texture_float");
- _supportsIntegerTextures = gl.isExtensionAvailable("GL_EXT_texture_integer");
- _supportsOneTwoComponentTextures = gl.isExtensionAvailable("GL_ARB_texture_rg");
-
+ // Support for texture formats
+ _supportsFloatTextures = gl.isExtensionAvailable("GL_ARB_texture_float");
+ _supportsIntegerTextures = gl.isExtensionAvailable("GL_EXT_texture_integer");
+ _supportsOneTwoComponentTextures = gl.isExtensionAvailable("GL_ARB_texture_rg");
+
// Check for support of fixed function dot3 environment settings
_supportsEnvDot3 = gl.isExtensionAvailable("GL_ARB_texture_env_dot3");
@@ -172,8 +177,8 @@ public class JoglContextCapabilities extends ContextCapabilities {
}
// Now determine the maximum number of supported texture units
- _numTotalTexUnits = Math.max(_numFragmentTexCoordUnits, Math.max(_numFixedTexUnits, Math.max(
- _numFragmentTexUnits, _numVertexTexUnits)));
+ _numTotalTexUnits = Math.max(_numFragmentTexCoordUnits,
+ Math.max(_numFixedTexUnits, Math.max(_numFragmentTexUnits, _numVertexTexUnits)));
// Check for S3 texture compression capability.
_supportsS3TCCompression = gl.isExtensionAvailable("GL_EXT_texture_compression_s3tc");
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);