From 77a4002c3d31afe28ddb1f618cb5d196cdce7384 Mon Sep 17 00:00:00 2001 From: Nehon Date: Fri, 16 May 2014 00:04:29 +0200 Subject: [PATCH] Added support for hardware srgb output (gamma correction). It can be toggled at render time. Works with lwjgl Couldn't test with Jogl and might be not working Not supported by mobile renderers --- .../renderer/android/OGLESShaderRenderer.java | 4 ++++ .../main/java/com/jme3/renderer/Renderer.java | 22 +++++++++++++++++++ .../java/com/jme3/system/NullRenderer.java | 3 +++ .../renderer/ios/IGLESShaderRenderer.java | 4 ++++ .../jme3/renderer/jogl/JoglGL1Renderer.java | 3 +++ .../com/jme3/renderer/jogl/JoglRenderer.java | 11 ++++++++++ .../jme3/system/jogl/JoglAbstractDisplay.java | 2 ++ .../system/jogl/JoglNewtAbstractDisplay.java | 2 ++ .../jme3/renderer/lwjgl/LwjglGL1Renderer.java | 4 ++++ .../jme3/renderer/lwjgl/LwjglRenderer.java | 14 +++++++++--- .../com/jme3/system/lwjgl/LwjglCanvas.java | 8 ++++--- .../com/jme3/system/lwjgl/LwjglContext.java | 1 + .../com/jme3/system/lwjgl/LwjglDisplay.java | 5 +++-- .../system/lwjgl/LwjglOffscreenBuffer.java | 5 +++-- 14 files changed, 78 insertions(+), 10 deletions(-) diff --git a/jme3-android/src/main/java/com/jme3/renderer/android/OGLESShaderRenderer.java b/jme3-android/src/main/java/com/jme3/renderer/android/OGLESShaderRenderer.java index e5b8be69b..632df4a1b 100644 --- a/jme3-android/src/main/java/com/jme3/renderer/android/OGLESShaderRenderer.java +++ b/jme3-android/src/main/java/com/jme3/renderer/android/OGLESShaderRenderer.java @@ -2532,4 +2532,8 @@ public class OGLESShaderRenderer implements Renderer { boundShader = null; lastFb = null; } + + public void setMainFrameBufferSrgb(boolean srgb) { + //TODO once opglES3.0 is supported maybe.... + } } diff --git a/jme3-core/src/main/java/com/jme3/renderer/Renderer.java b/jme3-core/src/main/java/com/jme3/renderer/Renderer.java index c2d2ec6c7..8480da616 100644 --- a/jme3-core/src/main/java/com/jme3/renderer/Renderer.java +++ b/jme3-core/src/main/java/com/jme3/renderer/Renderer.java @@ -313,4 +313,26 @@ public interface Renderer { *

*/ public void setAlphaToCoverage(boolean value); + + /** + * If enabled, color values rendered to the main framebuffer undergo + * linear -> sRGB conversion. + * + * This is identical to {@link FrameBuffer#setSrgb(boolean)} except it is toggled + * for the main framebuffer instead of an offscreen buffer. + * + * This should be set together with {@link Renderer#setLinearizeSrgbImages(boolean)} + * + * As a shorthand, the user can set {@link AppSettings#setSrgbPipeline(boolean)} to true + * to toggle both {@link Renderer#setLinearizeSrgbImages(boolean)} and + * {@link Renderer#setMainFrameBufferSrgb(boolean)} if the + * {@link Caps#} is supported by the GPU. + * + * @throws RendererException If the GPU hardware does not support sRGB. + * + * @seealso FrameBuffer#setSrgb(boolean) + * + * @seealso Caps#Srgb + */ + public void setMainFrameBufferSrgb(boolean srgb); } diff --git a/jme3-core/src/main/java/com/jme3/system/NullRenderer.java b/jme3-core/src/main/java/com/jme3/system/NullRenderer.java index 3bd21b17d..ce8e1a6c1 100644 --- a/jme3-core/src/main/java/com/jme3/system/NullRenderer.java +++ b/jme3-core/src/main/java/com/jme3/system/NullRenderer.java @@ -152,4 +152,7 @@ public class NullRenderer implements Renderer { public void setAlphaToCoverage(boolean value) { } + public void setMainFrameBufferSrgb(boolean srgb) { + } + } diff --git a/jme3-ios/src/main/java/com/jme3/renderer/ios/IGLESShaderRenderer.java b/jme3-ios/src/main/java/com/jme3/renderer/ios/IGLESShaderRenderer.java index d3af7eff3..72e9d9608 100644 --- a/jme3-ios/src/main/java/com/jme3/renderer/ios/IGLESShaderRenderer.java +++ b/jme3-ios/src/main/java/com/jme3/renderer/ios/IGLESShaderRenderer.java @@ -2572,4 +2572,8 @@ public class IGLESShaderRenderer implements Renderer { throw new UnsupportedOperationException("Unrecognized test function: " + testFunc); } } + + public void setMainFrameBufferSrgb(boolean srgb) { + + } } \ No newline at end of file diff --git a/jme3-jogl/src/main/java/com/jme3/renderer/jogl/JoglGL1Renderer.java b/jme3-jogl/src/main/java/com/jme3/renderer/jogl/JoglGL1Renderer.java index 74993a3b2..449d94b82 100644 --- a/jme3-jogl/src/main/java/com/jme3/renderer/jogl/JoglGL1Renderer.java +++ b/jme3-jogl/src/main/java/com/jme3/renderer/jogl/JoglGL1Renderer.java @@ -1258,4 +1258,7 @@ public class JoglGL1Renderer implements GL1Renderer { public void deleteBuffer(VertexBuffer vb) { } + + public void setMainFrameBufferSrgb(boolean srgb) { + } } diff --git a/jme3-jogl/src/main/java/com/jme3/renderer/jogl/JoglRenderer.java b/jme3-jogl/src/main/java/com/jme3/renderer/jogl/JoglRenderer.java index 0ce6b7e6d..89daea47a 100644 --- a/jme3-jogl/src/main/java/com/jme3/renderer/jogl/JoglRenderer.java +++ b/jme3-jogl/src/main/java/com/jme3/renderer/jogl/JoglRenderer.java @@ -2589,4 +2589,15 @@ public class JoglRenderer implements Renderer { renderMeshDefault(mesh, lod, count); // } } + + public void setMainFrameBufferSrgb(boolean srgb) { + //Gamma correction + if(srgb && GLContext.getCurrent().isExtensionAvailable("GL_ARB_framebuffer_sRGB")){ + GLContext.getCurrentGL().glEnable(GL3.GL_FRAMEBUFFER_SRGB); + logger.log(Level.FINER, "SRGB FrameBuffer enabled (Gamma Correction)"); + }else{ + GLContext.getCurrentGL().glDisable(GL3.GL_FRAMEBUFFER_SRGB); + } + + } } diff --git a/jme3-jogl/src/main/java/com/jme3/system/jogl/JoglAbstractDisplay.java b/jme3-jogl/src/main/java/com/jme3/system/jogl/JoglAbstractDisplay.java index a3fb53767..011fa53f2 100644 --- a/jme3-jogl/src/main/java/com/jme3/system/jogl/JoglAbstractDisplay.java +++ b/jme3-jogl/src/main/java/com/jme3/system/jogl/JoglAbstractDisplay.java @@ -164,6 +164,8 @@ public abstract class JoglAbstractDisplay extends JoglContext implements GLEvent } renderer = new JoglRenderer(); + + renderer.setMainFrameBufferSrgb(settings.getGammaCorrection()); } protected void startGLCanvas() { diff --git a/jme3-jogl/src/main/java/com/jme3/system/jogl/JoglNewtAbstractDisplay.java b/jme3-jogl/src/main/java/com/jme3/system/jogl/JoglNewtAbstractDisplay.java index c8ce3dc81..77b2c51ba 100644 --- a/jme3-jogl/src/main/java/com/jme3/system/jogl/JoglNewtAbstractDisplay.java +++ b/jme3-jogl/src/main/java/com/jme3/system/jogl/JoglNewtAbstractDisplay.java @@ -144,6 +144,8 @@ public abstract class JoglNewtAbstractDisplay extends JoglContext implements GLE } renderer = new JoglRenderer(); + + renderer.setMainFrameBufferSrgb(settings.getGammaCorrection()); } protected void startGLCanvas() { diff --git a/jme3-lwjgl/src/main/java/com/jme3/renderer/lwjgl/LwjglGL1Renderer.java b/jme3-lwjgl/src/main/java/com/jme3/renderer/lwjgl/LwjglGL1Renderer.java index 8ddc3eb4d..e94598ef4 100644 --- a/jme3-lwjgl/src/main/java/com/jme3/renderer/lwjgl/LwjglGL1Renderer.java +++ b/jme3-lwjgl/src/main/java/com/jme3/renderer/lwjgl/LwjglGL1Renderer.java @@ -1198,4 +1198,8 @@ public class LwjglGL1Renderer implements GL1Renderer { public void deleteBuffer(VertexBuffer vb) { } + + public void setMainFrameBufferSrgb(boolean srgb) { + + } } diff --git a/jme3-lwjgl/src/main/java/com/jme3/renderer/lwjgl/LwjglRenderer.java b/jme3-lwjgl/src/main/java/com/jme3/renderer/lwjgl/LwjglRenderer.java index 8fb0085f3..89f74ef25 100644 --- a/jme3-lwjgl/src/main/java/com/jme3/renderer/lwjgl/LwjglRenderer.java +++ b/jme3-lwjgl/src/main/java/com/jme3/renderer/lwjgl/LwjglRenderer.java @@ -55,9 +55,7 @@ import com.jme3.texture.Texture; import com.jme3.texture.Texture.WrapAxis; import com.jme3.util.BufferUtils; import com.jme3.util.ListMap; -import com.jme3.util.NativeObject; import com.jme3.util.NativeObjectManager; -import com.jme3.util.SafeArrayList; import java.nio.*; import java.util.EnumSet; import java.util.List; @@ -371,7 +369,7 @@ public class LwjglRenderer implements Renderer { caps.add(Caps.FrameBufferMRT); 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); @@ -2488,4 +2486,14 @@ public class LwjglRenderer implements Renderer { renderMeshDefault(mesh, lod, count); // } } + + public void setMainFrameBufferSrgb(boolean srgb) { + //Gamma correction + if(srgb && GLContext.getCapabilities().GL_ARB_framebuffer_sRGB){ + glEnable(GL30.GL_FRAMEBUFFER_SRGB); + logger.log(Level.FINER, "SRGB FrameBuffer enabled (Gamma Correction)"); + }else{ + glDisable(GL30.GL_FRAMEBUFFER_SRGB); + } + } } diff --git a/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglCanvas.java b/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglCanvas.java index 30db8590b..e7d9756fe 100644 --- a/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglCanvas.java +++ b/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglCanvas.java @@ -308,7 +308,8 @@ public class LwjglCanvas extends LwjglAbstractDisplay implements JmeCanvasContex 0, 0, 0, - settings.useStereo3D()); + settings.useStereo3D()) + .withSRGB(settings.getGammaCorrection()); } return pbufferFormat; }else{ @@ -322,7 +323,8 @@ public class LwjglCanvas extends LwjglAbstractDisplay implements JmeCanvasContex 0, 0, 0, - settings.useStereo3D()); + settings.useStereo3D()) + .withSRGB(settings.getGammaCorrection()); } return canvasFormat; } @@ -467,7 +469,7 @@ public class LwjglCanvas extends LwjglAbstractDisplay implements JmeCanvasContex }else{ Display.create(acquirePixelFormat(false)); } - + renderer.invalidateState(); }else{ // First create the pbuffer, if it is needed. diff --git a/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglContext.java b/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglContext.java index 290c3e400..04b8541c0 100644 --- a/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglContext.java +++ b/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglContext.java @@ -237,6 +237,7 @@ public abstract class LwjglContext implements JmeContext { }else{ assert false; } + renderer.setMainFrameBufferSrgb(settings.getGammaCorrection()); // Init input if (keyInput != null) { diff --git a/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglDisplay.java b/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglDisplay.java index 40590864a..cce6c0c06 100644 --- a/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglDisplay.java +++ b/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglDisplay.java @@ -91,8 +91,9 @@ public class LwjglDisplay extends LwjglAbstractDisplay { 0, 0, 0, - settings.useStereo3D()); - + settings.useStereo3D()) + .withSRGB(settings.getGammaCorrection()); + frameRate = settings.getFrameRate(); logger.log(Level.FINE, "Selected display mode: {0}", displayMode); diff --git a/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglOffscreenBuffer.java b/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglOffscreenBuffer.java index 7297db794..6d5da4563 100644 --- a/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglOffscreenBuffer.java +++ b/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglOffscreenBuffer.java @@ -65,8 +65,9 @@ public class LwjglOffscreenBuffer extends LwjglContext implements Runnable { 0, settings.getDepthBits(), settings.getStencilBits(), - samples); - + samples) + .withSRGB(settings.getGammaCorrection()); + width = settings.getWidth(); height = settings.getHeight(); try{