diff --git a/jme3-core/src/main/java/com/jme3/renderer/RenderContext.java b/jme3-core/src/main/java/com/jme3/renderer/RenderContext.java index ea6088afb9..ae51d09bdd 100644 --- a/jme3-core/src/main/java/com/jme3/renderer/RenderContext.java +++ b/jme3-core/src/main/java/com/jme3/renderer/RenderContext.java @@ -215,6 +215,11 @@ public class RenderContext { */ public FrameBuffer boundFB; + /** + * Convert writes to srgb target from linear space to srgb + */ + public boolean srgbWriteEnabled; + /** * Currently bound Renderbuffer. * @@ -412,6 +417,8 @@ private void init() { alphaFunc = RenderState.TestFunction.Greater; cullMode = RenderState.FaceCullMode.Off; + srgbWriteEnabled = false; + clearColor.set(0, 0, 0, 0); } diff --git a/jme3-core/src/main/java/com/jme3/renderer/opengl/GLRenderer.java b/jme3-core/src/main/java/com/jme3/renderer/opengl/GLRenderer.java index f4ae6fe0e1..a6662b0c38 100644 --- a/jme3-core/src/main/java/com/jme3/renderer/opengl/GLRenderer.java +++ b/jme3-core/src/main/java/com/jme3/renderer/opengl/GLRenderer.java @@ -106,6 +106,7 @@ public final class GLRenderer implements Renderer { private int clipX, clipY, clipW, clipH; private int defaultAnisotropicFilter = 1; private boolean linearizeSrgbImages; + private boolean mainFrameBufferSrgb; private HashSet extensions; private boolean generateMipmapsForFramebuffers = true; @@ -1829,6 +1830,7 @@ public void copyFrameBuffer(FrameBuffer src, FrameBuffer dst, boolean copyColor, int dstY1; int prevFBO = context.boundFBO; + FrameBuffer prevFB = context.boundFB; if (mainFbOverride != null) { if (src == null) { @@ -1870,6 +1872,8 @@ public void copyFrameBuffer(FrameBuffer src, FrameBuffer dst, boolean copyColor, dstY1 = dst.getHeight(); } + toggleFramebufferSrgb(dst); + int mask = 0; if(copyColor){ @@ -1886,6 +1890,9 @@ public void copyFrameBuffer(FrameBuffer src, FrameBuffer dst, boolean copyColor, glfbo.glBindFramebufferEXT(GLFbo.GL_FRAMEBUFFER_EXT, prevFBO); + context.boundFBO = prevFBO; + context.boundFB = prevFB; + toggleFramebufferSrgb(prevFB); } else { throw new RendererException("Framebuffer blitting not supported by the video hardware"); } @@ -2046,6 +2053,21 @@ private void bindFrameBuffer(FrameBuffer fb) { } } + private void toggleFramebufferSrgb(FrameBuffer fb) { + boolean isSrgb = fb == null ? mainFrameBufferSrgb : fb.isSrgb(); + + if (isSrgb != context.srgbWriteEnabled) { + if (caps.contains(Caps.Srgb)) { + if (isSrgb) { + gl.glEnable(GLExt.GL_FRAMEBUFFER_SRGB_EXT); + } else { + gl.glDisable(GLExt.GL_FRAMEBUFFER_SRGB_EXT); + } + context.srgbWriteEnabled = isSrgb; + } + } + } + public void updateFrameBuffer(FrameBuffer fb) { if (fb.getNumColorBuffers() == 0 && fb.getDepthBuffer() == null) { throw new IllegalArgumentException("The framebuffer: " + fb @@ -2179,6 +2201,7 @@ public void setFrameBuffer(FrameBuffer fb) { if (context.boundFB == fb) { if (fb == null || !fb.isUpdateNeeded()) { + toggleFramebufferSrgb(fb); return; } } @@ -2230,6 +2253,7 @@ public void setFrameBuffer(FrameBuffer fb) { if (fb.getName() != null) glext.glObjectLabel(GL3.GL_FRAMEBUFFER, fb.getId(), fb.getName()); } } + toggleFramebufferSrgb(fb); } @Override @@ -3487,17 +3511,13 @@ public void setMainFrameBufferSrgb(boolean enableSrgb) { logger.warning("sRGB framebuffer is not supported " + "by video hardware, but was requested."); + mainFrameBufferSrgb = false; return; } - setFrameBuffer(null); - - if (enableSrgb) { - gl.glEnable(GLExt.GL_FRAMEBUFFER_SRGB_EXT); - logger.log(Level.FINER, "sRGB FrameBuffer enabled (Gamma Correction)"); - } else { - gl.glDisable(GLExt.GL_FRAMEBUFFER_SRGB_EXT); - logger.log(Level.FINER, "sRGB FrameBuffer disabled (Gamma Correction)"); + mainFrameBufferSrgb = enableSrgb; + if (context.boundFB == null) { + toggleFramebufferSrgb(null); } } @@ -3595,7 +3615,7 @@ public boolean isMainFrameBufferSrgb() { if (!caps.contains(Caps.Srgb)) { return false; } else { - return gl.glIsEnabled(GLExt.GL_FRAMEBUFFER_SRGB_EXT); + return mainFrameBufferSrgb; } }