Browse Source

Refactor setting global & camera shader parameters to functions. Used both by Batch & View. Ensure that same parameters are set in both scene and quad (postprocess) rendering. Note that quad rendering still does not use the camera's real projection matrix to ensure stability.

Lasse Öörni 11 years ago
parent
commit
ee9868e29e
3 changed files with 87 additions and 86 deletions
  1. 4 68
      Source/Engine/Graphics/Batch.cpp
  2. 79 18
      Source/Engine/Graphics/View.cpp
  3. 4 0
      Source/Engine/Graphics/View.h

+ 4 - 68
Source/Engine/Graphics/Batch.cpp

@@ -207,81 +207,17 @@ void Batch::Prepare(View* view, bool setModelTransform) const
         graphics->SetDepthWrite(pass_->GetDepthWrite());
         graphics->SetDepthWrite(pass_->GetDepthWrite());
     }
     }
     
     
-    // Set shaders
+    // Set shaders first. The available shader parameters and their register/uniform positions depend on the currently set shaders
     graphics->SetShaders(vertexShader_, pixelShader_);
     graphics->SetShaders(vertexShader_, pixelShader_);
     
     
-    // Set global frame parameters
+    // Set global (per-frame) shader parameters
     if (graphics->NeedParameterUpdate(SP_FRAME, (void*)0))
     if (graphics->NeedParameterUpdate(SP_FRAME, (void*)0))
-    {
-        const FrameInfo& frame = view->GetFrameInfo();
-        graphics->SetShaderParameter(VSP_DELTATIME, frame.timeStep_);
-        graphics->SetShaderParameter(PSP_DELTATIME, frame.timeStep_);
-        
-        Scene* scene = view->GetScene();
-        if (scene)
-        {
-            float elapsedTime = scene->GetElapsedTime();
-            graphics->SetShaderParameter(VSP_ELAPSEDTIME, elapsedTime);
-            graphics->SetShaderParameter(PSP_ELAPSEDTIME, elapsedTime);
-        }
-    }
+        view->SetGlobalShaderParameters();
     
     
     // Set camera shader parameters
     // Set camera shader parameters
     unsigned cameraHash = overrideView_ ? (unsigned)(size_t)camera_ + 4 : (unsigned)(size_t)camera_;
     unsigned cameraHash = overrideView_ ? (unsigned)(size_t)camera_ + 4 : (unsigned)(size_t)camera_;
     if (graphics->NeedParameterUpdate(SP_CAMERA, reinterpret_cast<void*>(cameraHash)))
     if (graphics->NeedParameterUpdate(SP_CAMERA, reinterpret_cast<void*>(cameraHash)))
-    {
-        Matrix3x4 cameraEffectiveTransform = camera_->GetEffectiveWorldTransform();
-        
-        graphics->SetShaderParameter(VSP_CAMERAPOS, cameraEffectiveTransform.Translation());
-        graphics->SetShaderParameter(VSP_CAMERAROT, cameraEffectiveTransform.RotationMatrix());
-        graphics->SetShaderParameter(PSP_CAMERAPOS, cameraEffectiveTransform.Translation());
-        
-        float nearClip = camera_->GetNearClip();
-        float farClip = camera_->GetFarClip();
-        graphics->SetShaderParameter(VSP_NEARCLIP, nearClip);
-        graphics->SetShaderParameter(VSP_FARCLIP, farClip);
-        graphics->SetShaderParameter(PSP_NEARCLIP, nearClip);
-        graphics->SetShaderParameter(PSP_FARCLIP, farClip);
-
-        Vector4 depthMode = Vector4::ZERO;
-        if (camera_->IsOrthographic())
-        {
-            depthMode.x_ = 1.0f;
-            #ifdef USE_OPENGL
-            depthMode.z_ = 0.5f;
-            depthMode.w_ = 0.5f;
-            #else
-            depthMode.z_ = 1.0f;
-            #endif
-        }
-        else
-            depthMode.w_ = 1.0f / camera_->GetFarClip();
-        
-        graphics->SetShaderParameter(VSP_DEPTHMODE, depthMode);
-        
-        Vector3 nearVector, farVector;
-        camera_->GetFrustumSize(nearVector, farVector);
-        Vector4 viewportParams(farVector.x_, farVector.y_, farVector.z_, 0.0f);
-        graphics->SetShaderParameter(VSP_FRUSTUMSIZE, viewportParams);
-        
-        Matrix4 projection = camera_->GetProjection();
-        #ifdef USE_OPENGL
-        // Add constant depth bias manually to the projection matrix due to glPolygonOffset() inconsistency
-        float constantBias = 2.0f * graphics->GetDepthConstantBias();
-        // On OpenGL ES slope-scaled bias can not be guaranteed to be available, and the shadow filtering is more coarse,
-        // so use a higher constant bias
-        #ifdef GL_ES_VERSION_2_0
-        constantBias *= 2.0f;
-        #endif
-        projection.m22_ += projection.m32_ * constantBias;
-        projection.m23_ += projection.m33_ * constantBias;
-        #endif
-        
-        if (overrideView_)
-            graphics->SetShaderParameter(VSP_VIEWPROJ, projection);
-        else
-            graphics->SetShaderParameter(VSP_VIEWPROJ, projection * camera_->GetView());
-    }
+        view->SetCameraShaderParameters(camera_, true, overrideView_);
     
     
     // Set viewport shader parameters
     // Set viewport shader parameters
     IntVector2 rtSize = graphics->GetRenderTargetDimensions();
     IntVector2 rtSize = graphics->GetRenderTargetDimensions();

+ 79 - 18
Source/Engine/Graphics/View.cpp

@@ -599,6 +599,80 @@ Renderer* View::GetRenderer() const
     return renderer_;
     return renderer_;
 }
 }
 
 
+void View::SetGlobalShaderParameters()
+{
+    graphics_->SetShaderParameter(VSP_DELTATIME, frame_.timeStep_);
+    graphics_->SetShaderParameter(PSP_DELTATIME, frame_.timeStep_);
+    
+    if (scene_)
+    {
+        float elapsedTime = scene_->GetElapsedTime();
+        graphics_->SetShaderParameter(VSP_ELAPSEDTIME, elapsedTime);
+        graphics_->SetShaderParameter(PSP_ELAPSEDTIME, elapsedTime);
+    }
+}
+
+void View::SetCameraShaderParameters(Camera* camera, bool setProjection, bool overrideView)
+{
+    if (!camera)
+        return;
+    
+    Matrix3x4 cameraEffectiveTransform = camera->GetEffectiveWorldTransform();
+    
+    graphics_->SetShaderParameter(VSP_CAMERAPOS, cameraEffectiveTransform.Translation());
+    graphics_->SetShaderParameter(VSP_CAMERAROT, cameraEffectiveTransform.RotationMatrix());
+    graphics_->SetShaderParameter(PSP_CAMERAPOS, cameraEffectiveTransform.Translation());
+    
+    float nearClip = camera->GetNearClip();
+    float farClip = camera->GetFarClip();
+    graphics_->SetShaderParameter(VSP_NEARCLIP, nearClip);
+    graphics_->SetShaderParameter(VSP_FARCLIP, farClip);
+    graphics_->SetShaderParameter(PSP_NEARCLIP, nearClip);
+    graphics_->SetShaderParameter(PSP_FARCLIP, farClip);
+
+    Vector4 depthMode = Vector4::ZERO;
+    if (camera->IsOrthographic())
+    {
+        depthMode.x_ = 1.0f;
+        #ifdef USE_OPENGL
+        depthMode.z_ = 0.5f;
+        depthMode.w_ = 0.5f;
+        #else
+        depthMode.z_ = 1.0f;
+        #endif
+    }
+    else
+        depthMode.w_ = 1.0f / camera->GetFarClip();
+    
+    graphics_->SetShaderParameter(VSP_DEPTHMODE, depthMode);
+    
+    Vector3 nearVector, farVector;
+    camera->GetFrustumSize(nearVector, farVector);
+    Vector4 viewportParams(farVector.x_, farVector.y_, farVector.z_, 0.0f);
+    graphics_->SetShaderParameter(VSP_FRUSTUMSIZE, viewportParams);
+    
+    if (setProjection)
+    {
+        Matrix4 projection = camera->GetProjection();
+        #ifdef USE_OPENGL
+        // Add constant depth bias manually to the projection matrix due to glPolygonOffset() inconsistency
+        float constantBias = 2.0f * graphics->GetDepthConstantBias();
+        // On OpenGL ES slope-scaled bias can not be guaranteed to be available, and the shadow filtering is more coarse,
+        // so use a higher constant bias
+        #ifdef GL_ES_VERSION_2_0
+        constantBias *= 2.0f;
+        #endif
+        projection.m22_ += projection.m32_ * constantBias;
+        projection.m23_ += projection.m33_ * constantBias;
+        #endif
+        
+        if (overrideView)
+            graphics_->SetShaderParameter(VSP_VIEWPROJ, projection);
+        else
+            graphics_->SetShaderParameter(VSP_VIEWPROJ, projection * camera->GetView());
+    }
+}
+
 void View::GetDrawables()
 void View::GetDrawables()
 {
 {
     if (!camera_ || !octree_)
     if (!camera_ || !octree_)
@@ -1599,24 +1673,11 @@ void View::RenderQuad(RenderPathCommand& command)
     const HashMap<StringHash, Variant>& parameters = command.shaderParameters_;
     const HashMap<StringHash, Variant>& parameters = command.shaderParameters_;
     for (HashMap<StringHash, Variant>::ConstIterator k = parameters.Begin(); k != parameters.End(); ++k)
     for (HashMap<StringHash, Variant>::ConstIterator k = parameters.Begin(); k != parameters.End(); ++k)
         graphics_->SetShaderParameter(k->first_, k->second_);
         graphics_->SetShaderParameter(k->first_, k->second_);
-
-    graphics_->SetShaderParameter(VSP_DELTATIME, frame_.timeStep_);
-    graphics_->SetShaderParameter(PSP_DELTATIME, frame_.timeStep_);
-
-    if (scene_)
-    {
-        float elapsedTime = scene_->GetElapsedTime();
-        graphics_->SetShaderParameter(VSP_ELAPSEDTIME, elapsedTime);
-        graphics_->SetShaderParameter(PSP_ELAPSEDTIME, elapsedTime);
-    }
-
-    float nearClip = camera_ ? camera_->GetNearClip() : DEFAULT_NEARCLIP;
-    float farClip = camera_ ? camera_->GetFarClip() : DEFAULT_FARCLIP;
-    graphics_->SetShaderParameter(VSP_NEARCLIP, nearClip);
-    graphics_->SetShaderParameter(VSP_FARCLIP, farClip);
-    graphics_->SetShaderParameter(PSP_NEARCLIP, nearClip);
-    graphics_->SetShaderParameter(PSP_FARCLIP, farClip);
     
     
+    SetGlobalShaderParameters();
+    SetCameraShaderParameters(camera_, false, false);
+    
+    /// \todo Refactor into a function to set the viewport parameters
     float rtWidth = (float)rtSize_.x_;
     float rtWidth = (float)rtSize_.x_;
     float rtHeight = (float)rtSize_.y_;
     float rtHeight = (float)rtSize_.y_;
     float widthRange = 0.5f * viewSize_.x_ / rtWidth;
     float widthRange = 0.5f * viewSize_.x_ / rtWidth;
@@ -1850,7 +1911,7 @@ void View::BlitFramebuffer(Texture2D* source, RenderSurface* destination, bool d
     graphics_->SetDepthStencil(GetDepthStencil(destination));
     graphics_->SetDepthStencil(GetDepthStencil(destination));
     graphics_->SetViewport(viewRect_);
     graphics_->SetViewport(viewRect_);
     
     
-    String shaderName = "CopyFramebuffer";
+    static const String shaderName("CopyFramebuffer");
     graphics_->SetShaders(graphics_->GetShader(VS, shaderName), graphics_->GetShader(PS, shaderName));
     graphics_->SetShaders(graphics_->GetShader(VS, shaderName), graphics_->GetShader(PS, shaderName));
     
     
     float rtWidth = (float)rtSize_.x_;
     float rtWidth = (float)rtSize_.x_;

+ 4 - 0
Source/Engine/Graphics/View.h

@@ -147,6 +147,10 @@ public:
     const PODVector<Light*>& GetLights() const { return lights_; }
     const PODVector<Light*>& GetLights() const { return lights_; }
     /// Return light batch queues.
     /// Return light batch queues.
     const Vector<LightBatchQueue>& GetLightQueues() const { return lightQueues_; }
     const Vector<LightBatchQueue>& GetLightQueues() const { return lightQueues_; }
+    /// Set global (per-frame) shader parameters. Called by Batch and internally by View.
+    void SetGlobalShaderParameters();
+    /// Set camera-specific shader parameters. Called by Batch and internally by View.
+    void SetCameraShaderParameters(Camera* camera, bool setProjectionMatrix, bool overrideView);
     
     
 private:
 private:
     /// Query the octree for drawable objects.
     /// Query the octree for drawable objects.