瀏覽代碼

Fixed viewport calculation for rendertargets defined in the render path. If a target uses the RT divisor mode, scale the viewport, otherwise use full texture size (eg. for the bloom intermediate textures)
Undefined (zero) rendertarget size no longer uses the destination size automatically, instead the divisor needs to be specified.

Lasse Öörni 13 年之前
父節點
當前提交
d733091eb2
共有 4 個文件被更改,包括 48 次插入27 次删除
  1. 3 3
      Bin/CoreData/RenderPaths/Deferred.xml
  2. 3 3
      Bin/CoreData/RenderPaths/Prepass.xml
  3. 2 2
      Docs/Reference.dox
  4. 40 19
      Engine/Graphics/View.cpp

+ 3 - 3
Bin/CoreData/RenderPaths/Deferred.xml

@@ -1,7 +1,7 @@
 <renderpath>
-    <rendertarget name="albedo" format="rgba" />
-    <rendertarget name="normal" format="rgba" />
-    <rendertarget name="depth" format="lineardepth" />
+    <rendertarget name="albedo" rtsizedivisor="1 1" format="rgba" />
+    <rendertarget name="normal" rtsizedivisor="1 1" format="rgba" />
+    <rendertarget name="depth" rtsizedivisor="1 1" format="lineardepth" />
     <command type="clear" color="fog" depth="1.0" stencil="0" />
     <command type="scenepass" pass="deferred" marktostencil="true" vertexlights="true">
         <output index="0" name="viewport" />

+ 3 - 3
Bin/CoreData/RenderPaths/Prepass.xml

@@ -1,7 +1,7 @@
 <renderpath>
-    <rendertarget name="light" format="rgba" />
-    <rendertarget name="normal" format="rgba" />
-    <rendertarget name="depth" format="lineardepth" />
+    <rendertarget name="light" rtsizedivisor="1 1"  format="rgba" />
+    <rendertarget name="normal" rtsizedivisor="1 1" format="rgba" />
+    <rendertarget name="depth" rtsizedivisor="1 1"  format="lineardepth" />
     <command type="clear" color="fog" depth="1.0" stencil="0" />
     <command type="scenepass" pass="prepass" marktostencil="true">
         <output index="0" name="normal" />

+ 2 - 2
Docs/Reference.dox

@@ -692,9 +692,9 @@ The available commands are:
 - forwardlights: Render per-pixel forward lighting for opaque objects. Shadow maps are also rendered as necessary.
 - lightvolumes: Render deferred light volumes using the specified shaders. G-buffer textures can be bound as necessary.
 
-A render path can be constructed from a main XML file, and then other XML files (for example one for each post-processing effect) can be appended to it. Rendertargets and commands can be \ref RenderPath::SetActive "activated or deactivated" to switch eg. a post-processing effect on or off. To aid in this, they can be identified by tag names, for example the bloom effect marks itself with the tag "Bloom".
+A render path can be loaded from a main XML file by calling \ref RenderPath::LoadParameters "LoadParameters()", after which other XML files (for example one for each post-processing effect) can be appended to it by calling \ref RenderPath::Append "Append()". Rendertargets and commands can be activated or deactivated by calling \ref RenderPath::SetActive "SetActive()" to switch eg. a post-processing effect on or off. To aid in this, both can be identified by tag names, for example the bloom effect uses the tag "Bloom" for all of its rendertargets and commands.
 
-It is legal to both write to the destination viewport and sample from it during the same command: pingpong copies of its contents will be made automatically. If the viewport has hardware multisampling on, the multisampled backbuffer will be resolved to a texture before the first pass which samples it.
+It is legal to both write to the destination viewport and sample from it during the same command: pingpong copies of its contents will be made automatically. If the viewport has hardware multisampling on, the multisampled backbuffer will be resolved to a texture before the first command which samples it.
 
 The render path XML definition looks like this:
 

+ 40 - 19
Engine/Graphics/View.cpp

@@ -1312,6 +1312,7 @@ void View::ExecuteRenderPathCommands()
 void View::SetRenderTargets(const RenderPathCommand& command)
 {
     unsigned index = 0;
+    IntRect viewPort = viewRect_;
     
     while (index < command.outputNames_.Size())
     {
@@ -1321,7 +1322,40 @@ void View::SetRenderTargets(const RenderPathCommand& command)
         {
             StringHash nameHash(command.outputNames_[index]);
             if (renderTargets_.Contains(nameHash))
-                graphics_->SetRenderTarget(index, renderTargets_[nameHash]);
+            {
+                Texture2D* texture = renderTargets_[nameHash];
+                graphics_->SetRenderTarget(index, texture);
+                if (!index)
+                {
+                    // Determine viewport size from rendertarget info
+                    for (unsigned i = 0; i < renderPath_->renderTargets_.Size(); ++i)
+                    {
+                        const RenderTargetInfo& info = renderPath_->renderTargets_[i];
+                        if (!info.name_.Compare(command.outputNames_[index], false))
+                        {
+                            switch (info.sizeMode_)
+                            {
+                                // If absolute or a divided viewport size, use the full texture
+                            case SIZE_ABSOLUTE:
+                            case SIZE_VIEWPORTDIVISOR:
+                                viewPort = IntRect(0, 0, texture->GetWidth(), texture->GetHeight());
+                                break;
+                            
+                                // If a divided rendertarget size, retain the same viewport, but scaled
+                            case SIZE_RENDERTARGETDIVISOR:
+                                if (info.size_.x_ && info.size_.y_)
+                                {
+                                    viewPort = IntRect(viewRect_.left_ / info.size_.x_, viewRect_.top_ / info.size_.y_,
+                                        viewRect_.right_ / info.size_.x_, viewRect_.bottom_ / info.size_.y_);
+                                }
+                                break;
+                            }
+                            break;
+                        }
+                    }
+                }
+                
+            }
             else
                 graphics_->SetRenderTarget(0, (RenderSurface*)0);
         }
@@ -1336,7 +1370,7 @@ void View::SetRenderTargets(const RenderPathCommand& command)
     }
     
     graphics_->SetDepthStencil(GetDepthStencil(graphics_->GetRenderTarget(0)));
-    graphics_->SetViewport(viewRect_);
+    graphics_->SetViewport(viewPort);
     graphics_->SetColorWrite(true);
 }
 
@@ -1505,29 +1539,16 @@ void View::AllocateScreenBuffers()
         
         unsigned width = rtInfo.size_.x_;
         unsigned height = rtInfo.size_.y_;
-        if (!width || !height)
-        {
-            if (rtInfo.sizeMode_ != SIZE_VIEWPORTDIVISOR)
-            {
-                width = rtSize_.x_;
-                height = rtSize_.y_;
-            }
-            else
-            {
-                width = viewSize_.x_;
-                height = viewSize_.y_;
-            }
-        }
         
         if (rtInfo.sizeMode_ == SIZE_VIEWPORTDIVISOR)
         {
-            width = viewSize_.x_ / width;
-            height = viewSize_.y_ / height;
+            width = viewSize_.x_ / (width ? width : 1);
+            height = viewSize_.y_ / (height ? height : 1);
         }
         if (rtInfo.sizeMode_ == SIZE_RENDERTARGETDIVISOR)
         {
-            width = rtSize_.x_ / width;
-            height = rtSize_.y_ / height;
+            width = rtSize_.x_ / (width ? width : 1);
+            height = rtSize_.y_ / (height ? height : 1);
         }
         
         renderTargets_[StringHash(rtInfo.name_)] = renderer_->GetScreenBuffer(width, height, rtInfo.format_, rtInfo.filtered_);