Browse Source

If a view's renderpath has no scene passes, allow rendering it also when no scene, camera & octree are provided. Closes #267.

Lasse Öörni 11 years ago
parent
commit
6833f858dc

+ 2 - 7
Source/Engine/Graphics/Camera.cpp

@@ -34,11 +34,6 @@ namespace Urho3D
 
 extern const char* SCENE_CATEGORY;
 
-static const float DEFAULT_NEARCLIP = 0.1f;
-static const float DEFAULT_FARCLIP = 1000.0f;
-static const float DEFAULT_FOV = 45.0f;
-static const float DEFAULT_ORTHOSIZE = 20.0f;
-
 static const char* fillModeNames[] =
 {
     "Solid",
@@ -62,7 +57,7 @@ Camera::Camera(Context* context) :
     orthographic_(false),
     nearClip_(DEFAULT_NEARCLIP),
     farClip_(DEFAULT_FARCLIP),
-    fov_(DEFAULT_FOV),
+    fov_(DEFAULT_CAMERA_FOV),
     orthoSize_(DEFAULT_ORTHOSIZE),
     aspectRatio_(1.0f),
     zoom_(1.0f),
@@ -92,7 +87,7 @@ void Camera::RegisterObject(Context* context)
     ACCESSOR_ATTRIBUTE(Camera, VAR_BOOL, "Is Enabled", IsEnabled, SetEnabled, bool, true, AM_DEFAULT);
     ACCESSOR_ATTRIBUTE(Camera, VAR_FLOAT, "Near Clip", GetNearClip, SetNearClip, float, DEFAULT_NEARCLIP, AM_DEFAULT);
     ACCESSOR_ATTRIBUTE(Camera, VAR_FLOAT, "Far Clip", GetFarClip, SetFarClip, float, DEFAULT_FARCLIP, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(Camera, VAR_FLOAT, "FOV", GetFov, SetFov, float, DEFAULT_FOV, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE(Camera, VAR_FLOAT, "FOV", GetFov, SetFov, float, DEFAULT_CAMERA_FOV, AM_DEFAULT);
     ACCESSOR_ATTRIBUTE(Camera, VAR_FLOAT, "Aspect Ratio", GetAspectRatio, SetAspectRatioInternal, float, 1.0f, AM_DEFAULT);
     ENUM_ATTRIBUTE(Camera, "Fill Mode", fillMode_, fillModeNames, FILL_SOLID, AM_DEFAULT);
     ATTRIBUTE(Camera, VAR_BOOL, "Auto Aspect Ratio", autoAspectRatio_, true, AM_DEFAULT);

+ 5 - 0
Source/Engine/Graphics/Camera.h

@@ -30,6 +30,11 @@
 namespace Urho3D
 {
 
+static const float DEFAULT_NEARCLIP = 0.1f;
+static const float DEFAULT_FARCLIP = 1000.0f;
+static const float DEFAULT_CAMERA_FOV = 45.0f;
+static const float DEFAULT_ORTHOSIZE = 20.0f;
+
 static const unsigned VO_NONE = 0x0;
 static const unsigned VO_LOW_MATERIAL_QUALITY = 0x1;
 static const unsigned VO_DISABLE_SHADOWS = 0x2;

+ 3 - 3
Source/Engine/Graphics/Light.cpp

@@ -41,7 +41,7 @@ extern const char* SCENE_CATEGORY;
 
 static const LightType DEFAULT_LIGHTTYPE = LIGHT_POINT;
 static const float DEFAULT_RANGE = 10.0f;
-static const float DEFAULT_FOV = 30.0f;
+static const float DEFAULT_LIGHT_FOV = 30.0f;
 static const float DEFAULT_SPECULARINTENSITY = 1.0f;
 static const float DEFAULT_BRIGHTNESS = 1.0f;
 static const float DEFAULT_CONSTANTBIAS = 0.0001f;
@@ -95,7 +95,7 @@ Light::Light(Context* context) :
     specularIntensity_(DEFAULT_SPECULARINTENSITY),
     brightness_(DEFAULT_BRIGHTNESS),
     range_(DEFAULT_RANGE),
-    fov_(DEFAULT_FOV),
+    fov_(DEFAULT_LIGHT_FOV),
     aspectRatio_(1.0f),
     fadeDistance_(0.0f),
     shadowFadeDistance_(0.0f),
@@ -120,7 +120,7 @@ void Light::RegisterObject(Context* context)
     ACCESSOR_ATTRIBUTE(Light, VAR_FLOAT, "Specular Intensity", GetSpecularIntensity, SetSpecularIntensity, float, DEFAULT_SPECULARINTENSITY, AM_DEFAULT);
     ACCESSOR_ATTRIBUTE(Light, VAR_FLOAT, "Brightness Multiplier", GetBrightness, SetBrightness, float, DEFAULT_BRIGHTNESS, AM_DEFAULT);
     ACCESSOR_ATTRIBUTE(Light, VAR_FLOAT, "Range", GetRange, SetRange, float, DEFAULT_RANGE, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(Light, VAR_FLOAT, "Spot FOV", GetFov, SetFov, float, DEFAULT_FOV, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE(Light, VAR_FLOAT, "Spot FOV", GetFov, SetFov, float, DEFAULT_LIGHT_FOV, AM_DEFAULT);
     ACCESSOR_ATTRIBUTE(Light, VAR_FLOAT, "Spot Aspect Ratio", GetAspectRatio, SetAspectRatio, float, 1.0f, AM_DEFAULT);
     ACCESSOR_ATTRIBUTE(Light, VAR_RESOURCEREF, "Attenuation Texture", GetRampTextureAttr, SetRampTextureAttr, ResourceRef, ResourceRef(Texture2D::GetTypeStatic()), AM_DEFAULT);
     ACCESSOR_ATTRIBUTE(Light, VAR_RESOURCEREF, "Light Shape Texture", GetShapeTextureAttr, SetShapeTextureAttr, ResourceRef, ResourceRef(Texture2D::GetTypeStatic()), AM_DEFAULT);

+ 4 - 1
Source/Engine/Graphics/Renderer.cpp

@@ -596,7 +596,7 @@ void Renderer::Update(float timeStep)
         if (numViews_ == views_.Size())
             views_.Push(SharedPtr<View>(new View(context_)));
         
-        // Check if view can be defined successfully (has valid scene, camera and octree)
+        // Check if view can be defined successfully (has either valid scene, camera and octree, or no scene passes)
         assert(numViews_ < views_.Size());
         View* view = views_[numViews_];
         if (!view->Define(renderTarget, viewport))
@@ -606,6 +606,9 @@ void Renderer::Update(float timeStep)
         
         const IntRect& viewRect = viewport->GetRect();
         Scene* scene = viewport->GetScene();
+        if (!scene)
+            continue;
+        
         Octree* octree = scene->GetComponent<Octree>();
         
         // Update octree (perform early update for drawables which need that, and reinsert moved drawables.)

+ 57 - 44
Source/Engine/Graphics/View.cpp

@@ -310,37 +310,11 @@ View::~View()
 
 bool View::Define(RenderSurface* renderTarget, Viewport* viewport)
 {
-    Scene* scene = viewport->GetScene();
-    Camera* camera = viewport->GetCamera();
-    if (!scene || !camera || !camera->IsEnabledEffective())
-        return false;
-    
-    // If scene is loading asynchronously, it is incomplete and should not be rendered
-    if (scene->IsAsyncLoading())
-        return false;
-    
-    Octree* octree = scene->GetComponent<Octree>();
-    if (!octree)
-        return false;
-    
-    // Do not accept view if camera projection is illegal
-    // (there is a possibility of crash if occlusion is used and it can not clip properly)
-    if (!camera->IsProjectionValid())
+    renderPath_ = viewport->GetRenderPath();
+    if (!renderPath_)
         return false;
     
-    scene_ = scene;
-    octree_ = octree;
-    camera_ = camera;
-    cameraNode_ = camera->GetNode();
-    renderTarget_ = renderTarget;
-    renderPath_ = viewport->GetRenderPath();
-    
-    gBufferPassName_ = StringHash();
-    basePassName_  = PASS_BASE;
-    alphaPassName_ = PASS_ALPHA;
-    lightPassName_ = PASS_LIGHT;
-    litBasePassName_ = PASS_LITBASE;
-    litAlphaPassName_ = PASS_LITALPHA;
+    hasScenePasses_ = false;
     
     // Make sure that all necessary batch queues exist
     scenePasses_.Clear();
@@ -352,6 +326,8 @@ bool View::Define(RenderSurface* renderTarget, Viewport* viewport)
         
         if (command.type_ == CMD_SCENEPASS)
         {
+            hasScenePasses_ = true;
+            
             ScenePassInfo info;
             info.pass_ = command.pass_;
             info.allowInstancing_ = command.sortMode_ != SORT_BACKTOFRONT;
@@ -387,6 +363,42 @@ bool View::Define(RenderSurface* renderTarget, Viewport* viewport)
             lightPassName_ = command.pass_;
     }
     
+    
+    scene_ = viewport->GetScene();
+    camera_ = viewport->GetCamera();
+    octree_ = 0;
+    // Get default zone first in case we do not have zones defined
+    cameraZone_ = farClipZone_ = renderer_->GetDefaultZone();
+    
+    if (hasScenePasses_)
+    {
+        if (!scene_ || !camera_ || !camera_->IsEnabledEffective())
+            return false;
+        
+        // If scene is loading asynchronously, it is incomplete and should not be rendered
+        if (scene_->IsAsyncLoading())
+            return false;
+        
+        octree_ = scene_->GetComponent<Octree>();
+        if (!octree_)
+            return false;
+        
+        // Do not accept view if camera projection is illegal
+        // (there is a possibility of crash if occlusion is used and it can not clip properly)
+        if (!camera_->IsProjectionValid())
+            return false;
+    }
+    
+    cameraNode_ = camera_ ? camera_->GetNode() : (Node*)0;
+    renderTarget_ = renderTarget;
+    
+    gBufferPassName_ = StringHash();
+    basePassName_  = PASS_BASE;
+    alphaPassName_ = PASS_ALPHA;
+    lightPassName_ = PASS_LIGHT;
+    litBasePassName_ = PASS_LITBASE;
+    litAlphaPassName_ = PASS_LITALPHA;
+    
     // Go through commands to check for deferred rendering and other flags
     deferred_ = false;
     deferredAmbient_ = false;
@@ -447,7 +459,7 @@ bool View::Define(RenderSurface* renderTarget, Viewport* viewport)
     minInstances_ = renderer_->GetMinInstances();
     
     // Set possible quality overrides from the camera
-    unsigned viewOverrideFlags = camera_->GetViewOverrideFlags();
+    unsigned viewOverrideFlags = camera_ ? camera_->GetViewOverrideFlags() : VO_NONE;
     if (viewOverrideFlags & VO_LOW_MATERIAL_QUALITY)
         materialQuality_ = QUALITY_LOW;
     if (viewOverrideFlags & VO_DISABLE_SHADOWS)
@@ -464,9 +476,6 @@ bool View::Define(RenderSurface* renderTarget, Viewport* viewport)
 
 void View::Update(const FrameInfo& frame)
 {
-    if (!camera_ || !octree_)
-        return;
-    
     frame_.camera_ = camera_;
     frame_.timeStep_ = frame.timeStep_;
     frame_.frameNumber_ = frame.frameNumber_;
@@ -485,6 +494,9 @@ void View::Update(const FrameInfo& frame)
     for (HashMap<StringHash, BatchQueue>::Iterator i = batchQueues_.Begin(); i != batchQueues_.End(); ++i)
         i->second_.Clear(maxSortedInstances);
     
+    if (hasScenePasses_ && (!camera_ || !octree_))
+        return;
+    
     // Set automatic aspect ratio if required
     if (camera_->GetAutoAspectRatio())
         camera_->SetAspectRatioInternal((float)frame_.viewSize_.x_ / (float)frame_.viewSize_.y_);
@@ -495,7 +507,7 @@ void View::Update(const FrameInfo& frame)
 
 void View::Render()
 {
-    if (!octree_ || !camera_)
+    if (hasScenePasses_ && (!octree_ || !camera_))
         return;
     
     // Actually update geometry data now
@@ -514,15 +526,20 @@ void View::Render()
     
     // It is possible, though not recommended, that the same camera is used for multiple main views. Set automatic aspect ratio
     // again to ensure correct projection will be used
-    if (camera_->GetAutoAspectRatio())
-        camera_->SetAspectRatioInternal((float)(viewSize_.x_) / (float)(viewSize_.y_));
+    if (camera_)
+    {
+        if (camera_->GetAutoAspectRatio())
+            camera_->SetAspectRatioInternal((float)(viewSize_.x_) / (float)(viewSize_.y_));
+    }
     
     // Bind the face selection and indirection cube maps for point light shadows
+    #ifndef GL_ES_VERSION_2_0
     if (renderer_->GetDrawShadows())
     {
         graphics_->SetTexture(TU_FACESELECT, renderer_->GetFaceSelectCubeMap());
         graphics_->SetTexture(TU_INDIRECTION, renderer_->GetIndirectionCubeMap());
     }
+    #endif
     
     if (renderTarget_)
     {
@@ -550,7 +567,7 @@ void View::Render()
         BlitFramebuffer(static_cast<Texture2D*>(currentRenderTarget_->GetParentTexture()), renderTarget_, true);
     
     // If this is a main view, draw the associated debug geometry now
-    if (!renderTarget_)
+    if (!renderTarget_ && octree_)
     {
         DebugRenderer* debug = octree_->GetComponent<DebugRenderer>();
         if (debug && debug->IsEnabledEffective())
@@ -597,10 +614,6 @@ void View::GetDrawables()
     int bestPriority = M_MIN_INT;
     Vector3 cameraPos = cameraNode_->GetWorldPosition();
     
-    // Get default zone first in case we do not have zones defined
-    Zone* defaultZone = renderer_->GetDefaultZone();
-    cameraZone_ = farClipZone_ = defaultZone;
-    
     for (PODVector<Drawable*>::ConstIterator i = tempDrawables.Begin(); i != tempDrawables.End(); ++i)
     {
         Drawable* drawable = *i;
@@ -640,7 +653,7 @@ void View::GetDrawables()
             }
         }
     }
-    if (farClipZone_ == defaultZone)
+    if (farClipZone_ == renderer_->GetDefaultZone())
         farClipZone_ = cameraZone_;
     
     // If occlusion in use, get & render the occluders
@@ -1589,8 +1602,8 @@ void View::RenderQuad(RenderPathCommand& command)
         graphics_->SetShaderParameter(PSP_ELAPSEDTIME, elapsedTime);
     }
 
-    float nearClip = camera_->GetNearClip();
-    float farClip = camera_->GetFarClip();
+    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);

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

@@ -304,6 +304,8 @@ private:
     bool deferredAmbient_;
     /// Forward light base pass optimization flag. If in use, combine the base pass and first light for all opaque objects.
     bool useLitBase_;
+    /// Has scene passes flag. If no scene passes, view can be defined without a valid scene or camera to only perform quad rendering.
+    bool hasScenePasses_;
     /// Renderpath.
     RenderPath* renderPath_;
     /// Per-thread octree query results.