Procházet zdrojové kódy

Fixed missing framebuffer blit in OpenGL mode when postprocesses exist but are disabled.

Lasse Öörni před 14 roky
rodič
revize
bf8d7a53ca
2 změnil soubory, kde provedl 18 přidání a 27 odebrání
  1. 17 26
      Engine/Graphics/View.cpp
  2. 1 1
      Engine/Graphics/View.h

+ 17 - 26
Engine/Graphics/View.cpp

@@ -181,7 +181,15 @@ bool View::Define(RenderSurface* renderTarget, const Viewport& viewport)
     octree_ = octree;
     camera_ = viewport.camera_;
     renderTarget_ = renderTarget;
-    postProcesses_ = &viewport.postProcesses_;
+    
+    // Get active post-processing effects on the viewport
+    postProcesses_.Clear();
+    for (unsigned i = 0; i < viewport.postProcesses_.Size(); ++i)
+    {
+        PostProcess* effect = viewport.postProcesses_[i];
+        if (effect && effect->IsActive())
+            postProcesses_.Push(SharedPtr<PostProcess>(effect));
+    }
     
     // Validate the rect and calculate size. If zero rect, use whole rendertarget size
     int rtWidth = renderTarget ? renderTarget->GetWidth() : graphics_->GetWidth();
@@ -326,7 +334,7 @@ void View::Render()
     // Run post-processes or framebuffer blitting now
     if (screenBuffers_.Size())
     {
-        if (postProcesses_->Size())
+        if (postProcesses_.Size())
             RunPostProcesses();
         else
             BlitFramebuffer();
@@ -1204,24 +1212,20 @@ void View::AllocateScreenBuffers()
 {
     unsigned neededBuffers = 0;
     #ifdef USE_OPENGL
-    if (lightPrepass_)
+    // Due to FBO limitations, in OpenGL light pre-pass mode need to render to texture first and then blit to the backbuffer
+    if (lightPrepass_ && !renderTarget_)
         neededBuffers = 1;
     #endif
     
     unsigned postProcessPasses = 0;
-    for (unsigned i = 0; i < postProcesses_->Size(); ++i)
-    {
-        PostProcess* effect = postProcesses_->At(i);
-        if (effect && effect->IsActive())
-            postProcessPasses += effect->GetNumPasses();
-    }
+    for (unsigned i = 0; i < postProcesses_.Size(); ++i)
+        postProcessPasses += postProcesses_[i]->GetNumPasses();
     
     // If more than one post-process pass, need 2 buffers for ping-pong rendering
     if (postProcessPasses)
         neededBuffers = Min((int)postProcessPasses, 2);
     
     // Allocate screen buffers with filtering active in case the post-processing effects need that
-    screenBuffers_.Clear();
     for (unsigned i = 0; i < neededBuffers; ++i)
         screenBuffers_.Push(renderer_->GetScreenBuffer(rtSize_.x_, rtSize_.y_, Graphics::GetRGBFormat(), true));
 }
@@ -1257,7 +1261,6 @@ void View::BlitFramebuffer()
     #endif
     
     graphics_->SetShaderParameter(VSP_GBUFFEROFFSETS, bufferUVOffset);
-    
     graphics_->SetTexture(TU_DIFFUSE, screenBuffers_[0]);
     DrawFullscreenQuad(camera_, false);
 }
@@ -1276,21 +1279,9 @@ void View::RunPostProcesses()
     graphics_->SetScissorTest(false);
     graphics_->SetStencilTest(false);
     
-    // Find out the index of last active effect to see when the final output should be rendered
-    unsigned lastActiveEffect = 0;
-    for (unsigned i = 0; i < postProcesses_->Size(); ++i)
+    for (unsigned i = 0; i < postProcesses_.Size(); ++i)
     {
-        PostProcess* effect = postProcesses_->At(i);
-        if (!effect || !effect->IsActive())
-            continue;
-        lastActiveEffect = i;
-    }
-    
-    for (unsigned i = 0; i < postProcesses_->Size(); ++i)
-    {
-        PostProcess* effect = postProcesses_->At(i);
-        if (!effect || !effect->IsActive())
-            continue;
+        PostProcess* effect = postProcesses_[i];
         
         // For each effect, rendertargets can be re-used. Allocate them now
         renderer_->SaveScreenBufferAllocations();
@@ -1314,7 +1305,7 @@ void View::RunPostProcesses()
         for (unsigned j = 0; j < effect->GetNumPasses(); ++j)
         {
             PostProcessPass* pass = effect->GetPass(j);
-            bool lastPass = (i == lastActiveEffect) && (j == effect->GetNumPasses() - 1);
+            bool lastPass = (i == postProcesses_.Size() - 1) && (j == effect->GetNumPasses() - 1);
             bool swapBuffers = false;
             
             // Write depth on the last pass only

+ 1 - 1
Engine/Graphics/View.h

@@ -207,7 +207,7 @@ private:
     /// Color rendertarget to use.
     RenderSurface* renderTarget_;
     /// Post-processing effects.
-    const Vector<SharedPtr<PostProcess> >* postProcesses_;
+    Vector<SharedPtr<PostProcess> > postProcesses_;
     /// Intermediate screen buffers used in postprocessing and OpenGL light pre-pass framebuffer blit.
     PODVector<Texture2D*> screenBuffers_;
     /// Viewport rectangle.