Przeglądaj źródła

OpenGL sRGB framebuffer write mode.
If sRGB mode changed on a OpenGL Texture after it has already been created, recreate.

Lasse Öörni 12 lat temu
rodzic
commit
5cda61c090

+ 40 - 2
Engine/Graphics/OpenGL/OGLGraphics.cpp

@@ -161,6 +161,7 @@ Graphics::Graphics(Context* context_) :
     resizable_(false),
     vsync_(false),
     tripleBuffer_(false),
+    sRGB_(false),
     lightPrepassSupport_(false),
     deferredSupport_(false),
     anisotropySupport_(false),
@@ -443,7 +444,12 @@ bool Graphics::SetMode(int width, int height)
 
 void Graphics::SetSRGB(bool enabled)
 {
-    sRGB_ = enabled && sRGBSupport_;
+    enabled &= sRGBSupport_;
+    if (enabled != sRGB_)
+    {
+        sRGB_ = enabled;
+        impl_->fboDirty_ = true;
+    }
 }
 
 bool Graphics::ToggleFullscreen()
@@ -2053,6 +2059,11 @@ void Graphics::CleanupRenderSurface(RenderSurface* surface)
         glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, impl_->boundFbo_);
 }
 
+void Graphics::MarkFBODirty()
+{
+    impl_->fboDirty_ = true;
+}
+
 unsigned Graphics::GetAlphaFormat()
 {
     return GL_ALPHA;
@@ -2263,7 +2274,20 @@ void Graphics::CommitFramebuffer()
             impl_->boundFbo_ = impl_->systemFbo_;
         }
         
-        return;
+        #ifndef GL_ES_VERSION_2_0
+        // Disable/enable sRGB write
+        bool sRGBWrite = sRGB_;
+        if (sRGBWrite != impl_->sRGBWrite_)
+        {
+            if (sRGBWrite)
+                glEnable(GL_FRAMEBUFFER_SRGB_EXT);
+            else
+                glDisable(GL_FRAMEBUFFER_SRGB_EXT);
+            impl_->sRGBWrite_ = sRGBWrite;
+        }
+        #endif
+
+	    return;
     }
     
     // Search for a new framebuffer based on format & size, or create new
@@ -2421,6 +2445,19 @@ void Graphics::CommitFramebuffer()
             i->second_.depthAttachment_ = 0;
         }
     }
+    
+    #ifndef GL_ES_VERSION_2_0
+    // Disable/enable sRGB write
+    bool sRGBWrite = renderTargets_[0] ? renderTargets_[0]->GetParentTexture()->GetSRGB() : sRGB_;
+    if (sRGBWrite != impl_->sRGBWrite_)
+    {
+        if (sRGBWrite)
+            glEnable(GL_FRAMEBUFFER_SRGB_EXT);
+        else
+            glDisable(GL_FRAMEBUFFER_SRGB_EXT);
+        impl_->sRGBWrite_ = sRGBWrite;
+    }
+    #endif
 }
 
 bool Graphics::CheckFramebuffer()
@@ -2498,6 +2535,7 @@ void Graphics::ResetCachedState()
     impl_->activeTexture_ = 0;
     impl_->enabledAttributes_ = 0;
     impl_->boundFbo_ = impl_->systemFbo_;
+    impl_->sRGBWrite_ = false;
     
     // Set initial state to match Direct3D
     if (impl_->context_)

+ 2 - 0
Engine/Graphics/OpenGL/OGLGraphics.h

@@ -354,6 +354,8 @@ public:
     void Restore();
     /// Clean up a render surface from all FBOs.
     void CleanupRenderSurface(RenderSurface* surface);
+    /// Mark the FBO needing an update.
+    void MarkFBODirty();
     
     /// Return the API-specific alpha texture format.
     static unsigned GetAlphaFormat();

+ 2 - 0
Engine/Graphics/OpenGL/OGLGraphicsImpl.h

@@ -119,6 +119,8 @@ private:
     HashMap<unsigned long long, FrameBufferObject> frameBuffers_;
     /// Need FBO commit flag.
     bool fboDirty_;
+    /// sRGB write mode flag.
+    bool sRGBWrite_;
 };
 
 }

+ 15 - 1
Engine/Graphics/OpenGL/OGLTexture.cpp

@@ -27,6 +27,7 @@
 #include "Log.h"
 #include "Material.h"
 #include "Profiler.h"
+#include "RenderSurface.h"
 #include "ResourceCache.h"
 #include "StringUtils.h"
 #include "Texture.h"
@@ -122,7 +123,20 @@ void Texture::SetBorderColor(const Color& color)
 
 void Texture::SetSRGB(bool enable)
 {
-    sRGB_ = enable;
+    if (graphics_)
+        enable &= graphics_->GetSRGBSupport();
+    
+    if (enable != sRGB_)
+    {
+        sRGB_ = enable;
+        // If texture had already been created, must recreate it to set the sRGB texture format
+        if (object_)
+            Create();
+        
+        // If texture in use in the framebuffer, mark it dirty
+        if (graphics_ && graphics_->GetRenderTarget(0) && graphics_->GetRenderTarget(0)->GetParentTexture() == this)
+            graphics_->MarkFBODirty();
+    }
 }
 
 void Texture::SetBackupTexture(Texture* texture)

+ 2 - 0
Engine/Graphics/OpenGL/OGLTexture.h

@@ -117,6 +117,8 @@ public:
 protected:
     /// Check whether texture memory budget has been exceeded. Free unused materials in that case to release the texture references.
     void CheckTextureBudget(ShortStringHash type);
+    /// Create texture.
+    virtual bool Create() { return true; }
     
     /// Texture usage type.
     TextureUsage usage_;

+ 4 - 2
Engine/Graphics/OpenGL/OGLTexture2D.h

@@ -64,9 +64,11 @@ public:
     /// Return render surface.
     RenderSurface* GetRenderSurface() const { return renderSurface_; }
     
-private:
+protected:
     /// Create texture.
-    bool Create();
+    virtual bool Create();
+    
+private:
     /// Handle render surface update event.
     void HandleRenderSurfaceUpdate(StringHash eventType, VariantMap& eventData);
     

+ 4 - 2
Engine/Graphics/OpenGL/OGLTextureCube.h

@@ -68,9 +68,11 @@ public:
     /// Return render surface for one face.
     RenderSurface* GetRenderSurface(CubeMapFace face) const { return renderSurfaces_[face]; }
     
-private:
+protected:
     /// Create texture.
-    bool Create();
+    virtual bool Create();
+    
+private:
     /// Handle render surface update event.
     void HandleRenderSurfaceUpdate(StringHash eventType, VariantMap& eventData);