Browse Source

Graphics code cleanup. Remove the GraphicsFeatures event, as now the features can not change during runtime. Move all OpenGL extensions checks to CheckFeatureSupport(). Fix an AMD GLSL compilation bug, which caused buggy 4-sample shadows.

Lasse Öörni 10 years ago
parent
commit
2961166acb

+ 0 - 2
Source/Urho3D/Graphics/Direct3D11/D3D11Graphics.cpp

@@ -2385,8 +2385,6 @@ void Graphics::CheckFeatureSupport()
     dummyColorFormat_ = DXGI_FORMAT_UNKNOWN;
     sRGBSupport_ = true;
     sRGBWriteSupport_ = true;
-    
-    SendEvent(E_GRAPHICSFEATURES);
 }
 
 void Graphics::ResetCachedState()

+ 0 - 2
Source/Urho3D/Graphics/Direct3D9/D3D9Graphics.cpp

@@ -2562,8 +2562,6 @@ void Graphics::CheckFeatureSupport()
     /// \todo Should be checked for each texture format separately
     sRGBSupport_ = impl_->CheckFormatSupport(D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_SRGBREAD, D3DRTYPE_TEXTURE);
     sRGBWriteSupport_ = impl_->CheckFormatSupport(D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_SRGBWRITE, D3DRTYPE_TEXTURE);
-    
-    SendEvent(E_GRAPHICSFEATURES);
 }
 
 void Graphics::ResetDevice()

+ 0 - 5
Source/Urho3D/Graphics/GraphicsEvents.h

@@ -44,11 +44,6 @@ EVENT(E_WINDOWPOS, WindowPos)
     PARAM(P_Y, Y);                          // int
 }
 
-/// Graphics features checked.
-EVENT(E_GRAPHICSFEATURES, GraphicsFeatures)
-{
-}
-
 /// Request for queuing autoupdated rendersurfaces.
 EVENT(E_RENDERSURFACEUPDATE, RenderSurfaceUpdate)
 {

+ 49 - 42
Source/Urho3D/Graphics/OpenGL/OGLGraphics.cpp

@@ -160,7 +160,9 @@ static unsigned glesDepthStencilFormat = GL_DEPTH_COMPONENT16;
 static unsigned glesReadableDepthFormat = GL_DEPTH_COMPONENT;
 #endif
 
-bool CheckExtension(String& extensions, const String& name)
+static String extensions;
+
+bool CheckExtension(const String& name)
 {
     if (extensions.Empty())
         extensions = (const char*)glGetString(GL_EXTENSIONS);
@@ -522,7 +524,7 @@ bool Graphics::SetMode(int width, int height, bool fullscreen, bool borderless,
     Clear(CLEAR_COLOR);
     SDL_GL_SwapWindow(impl_->window_);
     
-    CheckFeatureSupport(extensions);
+    CheckFeatureSupport();
     
     #ifdef URHO3D_LOGGING
     String msg;
@@ -2417,6 +2419,9 @@ void Graphics::Restore()
             return;
         }
 
+        // Clear cached extensions string from the previous context
+        extensions.Clear();
+
         // Initialize OpenGL extensions library (desktop only)
         #ifndef GL_ES_VERSION_2_0
         GLenum err = glewInit();
@@ -2435,13 +2440,6 @@ void Graphics::Restore()
             unsigned vertexArrayObject;
             glGenVertexArrays(1, &vertexArrayObject);
             glBindVertexArray(vertexArrayObject);
-
-            // Work around GLEW failure to check extensions properly from a GL3 context
-            instancingSupport_ = true;
-            dxtTextureSupport_ = true;
-            anisotropySupport_ = true;
-            sRGBSupport_ = true;
-            sRGBWriteSupport_ = true;
         }
         else if (GLEW_VERSION_2_0)
         {
@@ -2453,37 +2451,12 @@ void Graphics::Restore()
 
             gl3Support = false;
             apiName_ = "GL2";
-
-            instancingSupport_ = GLEW_ARB_instanced_arrays != 0;
-            dxtTextureSupport_ = GLEW_EXT_texture_compression_s3tc != 0;
-            anisotropySupport_ = GLEW_EXT_texture_filter_anisotropic != 0;
-            sRGBSupport_ = GLEW_EXT_texture_sRGB != 0;
-            sRGBWriteSupport_ = GLEW_EXT_framebuffer_sRGB != 0;
         }
         else
         {
             LOGERROR("OpenGL 2.0 is required");
             return;
         }
-
-        // Set up instancing divisors if supported
-        if (gl3Support)
-        {
-            glVertexAttribDivisor(ELEMENT_INSTANCEMATRIX1, 1);
-            glVertexAttribDivisor(ELEMENT_INSTANCEMATRIX2, 1);
-            glVertexAttribDivisor(ELEMENT_INSTANCEMATRIX3, 1);
-        }
-        else if (instancingSupport_)
-        {
-            glVertexAttribDivisorARB(ELEMENT_INSTANCEMATRIX1, 1);
-            glVertexAttribDivisorARB(ELEMENT_INSTANCEMATRIX2, 1);
-            glVertexAttribDivisorARB(ELEMENT_INSTANCEMATRIX3, 1);
-        }
-
-        #else
-        dxtTextureSupport_ = CheckExtension(extensions, "EXT_texture_compression_dxt1");
-        etcTextureSupport_ = CheckExtension(extensions, "OES_compressed_ETC1_RGB8_texture");
-        pvrtcTextureSupport_ = CheckExtension(extensions, "IMG_texture_compression_pvrtc");
         #endif
 
         // Set up texture data read/write alignment. It is important that this is done before uploading any texture data
@@ -2740,7 +2713,7 @@ void Graphics::CreateWindowIcon()
     }
 }
 
-void Graphics::CheckFeatureSupport(String& extensions)
+void Graphics::CheckFeatureSupport()
 {
     // Check supported features: light pre-pass, deferred rendering and hardware depth texture
     lightPrepassSupport_ = false;
@@ -2749,10 +2722,39 @@ void Graphics::CheckFeatureSupport(String& extensions)
     int numSupportedRTs = 1;
     
     #ifndef GL_ES_VERSION_2_0
-    if (!gl3Support)
-        glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS_EXT, &numSupportedRTs);
-    else
+    if (gl3Support)
+    {
+        // Work around GLEW failure to check extensions properly from a GL3 context
+        instancingSupport_ = true;
+        dxtTextureSupport_ = true;
+        anisotropySupport_ = true;
+        sRGBSupport_ = true;
+        sRGBWriteSupport_ = true;
+
+        glVertexAttribDivisor(ELEMENT_INSTANCEMATRIX1, 1);
+        glVertexAttribDivisor(ELEMENT_INSTANCEMATRIX2, 1);
+        glVertexAttribDivisor(ELEMENT_INSTANCEMATRIX3, 1);
+
         glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS, &numSupportedRTs);
+    }
+    else
+    {
+        instancingSupport_ = GLEW_ARB_instanced_arrays != 0;
+        dxtTextureSupport_ = GLEW_EXT_texture_compression_s3tc != 0;
+        anisotropySupport_ = GLEW_EXT_texture_filter_anisotropic != 0;
+        sRGBSupport_ = GLEW_EXT_texture_sRGB != 0;
+        sRGBWriteSupport_ = GLEW_EXT_framebuffer_sRGB != 0;
+
+        // Set up instancing divisors if supported
+        if (instancingSupport_)
+        {
+            glVertexAttribDivisorARB(ELEMENT_INSTANCEMATRIX1, 1);
+            glVertexAttribDivisorARB(ELEMENT_INSTANCEMATRIX2, 1);
+            glVertexAttribDivisorARB(ELEMENT_INSTANCEMATRIX3, 1);
+        }
+
+        glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS_EXT, &numSupportedRTs);
+    }
 
     // Must support 2 rendertargets for light pre-pass, and 4 for deferred
     if (numSupportedRTs >= 2)
@@ -2770,15 +2772,20 @@ void Graphics::CheckFeatureSupport(String& extensions)
     #endif
     
     #else
+    // Check for supported compressed texture formats
+    dxtTextureSupport_ = CheckExtension("EXT_texture_compression_dxt1");
+    etcTextureSupport_ = CheckExtension("OES_compressed_ETC1_RGB8_texture");
+    pvrtcTextureSupport_ = CheckExtension("IMG_texture_compression_pvrtc");
+
     // Check for best supported depth renderbuffer format for GLES2
-    if (CheckExtension(extensions, "GL_OES_depth24"))
+    if (CheckExtension("GL_OES_depth24"))
         glesDepthStencilFormat = GL_DEPTH_COMPONENT24_OES;
-    if (CheckExtension(extensions, "GL_OES_packed_depth_stencil"))
+    if (CheckExtension("GL_OES_packed_depth_stencil"))
         glesDepthStencilFormat = GL_DEPTH24_STENCIL8_OES;
     #ifdef EMSCRIPTEN
-    if (!CheckExtension(extensions, "WEBGL_depth_texture"))
+    if (!CheckExtension("WEBGL_depth_texture"))
     #else
-    if (!CheckExtension(extensions, "GL_OES_depth_texture"))
+    if (!CheckExtension("GL_OES_depth_texture"))
     #endif
     {
         shadowMapFormat_ = 0;

+ 1 - 1
Source/Urho3D/Graphics/OpenGL/OGLGraphics.h

@@ -448,7 +448,7 @@ private:
     /// Create the application window icon.
     void CreateWindowIcon();
     /// Check supported rendering features.
-    void CheckFeatureSupport(String& extensions);
+    void CheckFeatureSupport();
     /// Prepare for draw call. Update constant buffers and setup the FBO.
     void PrepareDraw();
     /// Clean up all framebuffers. Called when destroying the context.

+ 0 - 8
Source/Urho3D/Graphics/Renderer.cpp

@@ -279,7 +279,6 @@ Renderer::Renderer(Context* context) :
     resetViews_(false)
 {
     SubscribeToEvent(E_SCREENMODE, HANDLER(Renderer, HandleScreenMode));
-    SubscribeToEvent(E_GRAPHICSFEATURES, HANDLER(Renderer, HandleGraphicsFeatures));
     
     // Try to initialize right now, but skip if screen mode is not yet set
     Initialize();
@@ -1711,13 +1710,6 @@ void Renderer::HandleScreenMode(StringHash eventType, VariantMap& eventData)
         resetViews_ = true;
 }
 
-void Renderer::HandleGraphicsFeatures(StringHash eventType, VariantMap& eventData)
-{
-    // Reinitialize if already initialized
-    if (initialized_)
-        Initialize();
-}
-
 void Renderer::HandleRenderUpdate(StringHash eventType, VariantMap& eventData)
 {
     using namespace RenderUpdate;

+ 0 - 2
Source/Urho3D/Graphics/Renderer.h

@@ -356,8 +356,6 @@ private:
     void ResetBuffers();
     /// Handle screen mode event.
     void HandleScreenMode(StringHash eventType, VariantMap& eventData);
-    /// Handle graphics features (re)check event. Event only sent by D3D9Graphics class.
-    void HandleGraphicsFeatures(StringHash eventType, VariantMap& eventData);
     /// Handle render update event.
     void HandleRenderUpdate(StringHash eventType, VariantMap& eventData);
     

+ 8 - 13
bin/CoreData/Shaders/GLSL/Lighting.glsl

@@ -136,21 +136,16 @@ float GetShadow(vec4 shadowPos)
                 vec2 offsets = cShadowMapInvSize;
             #endif
             #ifndef GL3
-                vec4 inLight = vec4(
-                    shadow2DProj(sShadowMap, shadowPos).r,
-                    shadow2DProj(sShadowMap, vec4(shadowPos.x + offsets.x, shadowPos.yzw)).r,
-                    shadow2DProj(sShadowMap, vec4(shadowPos.x, shadowPos.y + offsets.y, shadowPos.zw)).r,
-                    shadow2DProj(sShadowMap, vec4(shadowPos.xy + offsets.xy, shadowPos.zw)).r
-                );
+                return cShadowIntensity.y + cShadowIntensity.x * (shadow2DProj(sShadowMap, shadowPos).r +
+                    shadow2DProj(sShadowMap, vec4(shadowPos.x + offsets.x, shadowPos.yzw)).r +
+                    shadow2DProj(sShadowMap, vec4(shadowPos.x, shadowPos.y + offsets.y, shadowPos.zw)).r +
+                    shadow2DProj(sShadowMap, vec4(shadowPos.xy + offsets.xy, shadowPos.zw)).r);
             #else
-                vec4 inLight = vec4(
-                    textureProj(sShadowMap, shadowPos),
-                    textureProj(sShadowMap, vec4(shadowPos.x + offsets.x, shadowPos.yzw)),
-                    textureProj(sShadowMap, vec4(shadowPos.x, shadowPos.y + offsets.y, shadowPos.zw)),
-                    textureProj(sShadowMap, vec4(shadowPos.xy + offsets.xy, shadowPos.zw))
-                );
+                return cShadowIntensity.y + cShadowIntensity.x * (textureProj(sShadowMap, shadowPos) +
+                    textureProj(sShadowMap, vec4(shadowPos.x + offsets.x, shadowPos.yzw)) +
+                    textureProj(sShadowMap, vec4(shadowPos.x, shadowPos.y + offsets.y, shadowPos.zw)) +
+                    textureProj(sShadowMap, vec4(shadowPos.xy + offsets.xy, shadowPos.zw)));
             #endif
-            return cShadowIntensity.y + dot(inLight, vec4(cShadowIntensity.x));
         #else
             // Take one sample
             #ifndef GL3