From 6093cbadbe67dbf8100fbe91cfc7985cb33263d0 Mon Sep 17 00:00:00 2001 From: Riccardo Balbo Date: Thu, 30 Apr 2026 00:54:41 +0200 Subject: [PATCH 1/4] toggle srgb on per framebuffer basis --- .../java/com/jme3/renderer/RenderContext.java | 5 +++ .../com/jme3/renderer/opengl/GLRenderer.java | 38 ++++++++++++++----- 2 files changed, 34 insertions(+), 9 deletions(-) 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..8a7fb2229d 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. * 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..9a427de7df 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.SrgbWriteControl) && 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; } } From 001ded410ef9c0fb0650b6c9f01cd6d292a4aa05 Mon Sep 17 00:00:00 2001 From: Riccardo Balbo Date: Thu, 30 Apr 2026 01:00:25 +0200 Subject: [PATCH 2/4] fix merge --- .../src/main/java/com/jme3/renderer/opengl/GLRenderer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 9a427de7df..474800d4cb 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 @@ -2057,7 +2057,7 @@ private void toggleFramebufferSrgb(FrameBuffer fb) { boolean isSrgb = fb == null ? mainFrameBufferSrgb : fb.isSrgb(); if (isSrgb != context.srgbWriteEnabled) { - if (caps.contains(Caps.SrgbWriteControl) && caps.contains(Caps.Srgb)) { + if (caps.contains(Caps.Srgb)) { if (isSrgb) { gl.glEnable(GLExt.GL_FRAMEBUFFER_SRGB_EXT); } else { From 77d8994c8e456a582d2e67aeaf624007a433745b Mon Sep 17 00:00:00 2001 From: Riccardo Balbo Date: Thu, 30 Apr 2026 13:37:54 +0200 Subject: [PATCH 3/4] fix --- .../src/main/java/com/jme3/renderer/opengl/GLRenderer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 474800d4cb..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 @@ -2063,8 +2063,8 @@ private void toggleFramebufferSrgb(FrameBuffer fb) { } else { gl.glDisable(GLExt.GL_FRAMEBUFFER_SRGB_EXT); } + context.srgbWriteEnabled = isSrgb; } - context.srgbWriteEnabled = isSrgb; } } From d9902d276f2c192b06492f599e1b755f10314017 Mon Sep 17 00:00:00 2001 From: Riccardo Balbo Date: Thu, 30 Apr 2026 13:51:37 +0200 Subject: [PATCH 4/4] reset srgbWriteEnabled on init --- jme3-core/src/main/java/com/jme3/renderer/RenderContext.java | 2 ++ 1 file changed, 2 insertions(+) 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 8a7fb2229d..ae51d09bdd 100644 --- a/jme3-core/src/main/java/com/jme3/renderer/RenderContext.java +++ b/jme3-core/src/main/java/com/jme3/renderer/RenderContext.java @@ -417,6 +417,8 @@ private void init() { alphaFunc = RenderState.TestFunction.Greater; cullMode = RenderState.FaceCullMode.Off; + srgbWriteEnabled = false; + clearColor.set(0, 0, 0, 0); }