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{