X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dali-scene3d%2Finternal%2Fcontrols%2Fscene-view%2Fscene-view-impl.cpp;h=bb44ab7edbab55fdb59ed962beecadc19a99abd9;hb=d3ab7a4cc307562e687de2b2751f2f0a687c2835;hp=99ddef235ba394da411d09cfeb83b03d6d02e4d6;hpb=8dd0fbf1eae17419bf44948be77493c3c0e75262;p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git diff --git a/dali-scene3d/internal/controls/scene-view/scene-view-impl.cpp b/dali-scene3d/internal/controls/scene-view/scene-view-impl.cpp index 99ddef2..bb44ab7 100644 --- a/dali-scene3d/internal/controls/scene-view/scene-view-impl.cpp +++ b/dali-scene3d/internal/controls/scene-view/scene-view-impl.cpp @@ -25,17 +25,22 @@ #include #include #include +#include +#include #include +#include #include +#include #include #include +#include +#include // INTERNAL INCLUDES -#include +#include +#include #include -#include - using namespace Dali; namespace Dali @@ -55,16 +60,125 @@ BaseHandle Create() DALI_TYPE_REGISTRATION_BEGIN(Scene3D::SceneView, Toolkit::Control, Create); DALI_TYPE_REGISTRATION_END() -Property::Index RENDERING_BUFFER = Dali::Toolkit::Control::CONTROL_PROPERTY_END_INDEX + 1; +Property::Index RENDERING_BUFFER = Dali::Toolkit::Control::CONTROL_PROPERTY_END_INDEX + 1; +constexpr int32_t DEFAULT_ORIENTATION = 0; + +constexpr uint8_t DEFAULT_FRAME_BUFFER_MULTI_SAMPLING_LEVEL = 4u; + +static constexpr std::string_view SKYBOX_INTENSITY_STRING = "uIntensity"; + +Dali::Actor CreateSkybox() +{ + struct Vertex + { + Vector3 aPosition; + }; + + Vertex skyboxVertices[] = { + // back + {Vector3(-1.0f, 1.0f, -1.0f)}, + {Vector3(-1.0f, -1.0f, -1.0f)}, + {Vector3(1.0f, -1.0f, -1.0f)}, + {Vector3(1.0f, -1.0f, -1.0f)}, + {Vector3(1.0f, 1.0f, -1.0f)}, + {Vector3(-1.0f, 1.0f, -1.0f)}, + + // left + {Vector3(-1.0f, -1.0f, 1.0f)}, + {Vector3(-1.0f, -1.0f, -1.0f)}, + {Vector3(-1.0f, 1.0f, -1.0f)}, + {Vector3(-1.0f, 1.0f, -1.0f)}, + {Vector3(-1.0f, 1.0f, 1.0f)}, + {Vector3(-1.0f, -1.0f, 1.0f)}, + + // right + {Vector3(1.0f, -1.0f, -1.0f)}, + {Vector3(1.0f, -1.0f, 1.0f)}, + {Vector3(1.0f, 1.0f, 1.0f)}, + {Vector3(1.0f, 1.0f, 1.0f)}, + {Vector3(1.0f, 1.0f, -1.0f)}, + {Vector3(1.0f, -1.0f, -1.0f)}, + + // front + {Vector3(-1.0f, -1.0f, 1.0f)}, + {Vector3(-1.0f, 1.0f, 1.0f)}, + {Vector3(1.0f, 1.0f, 1.0f)}, + {Vector3(1.0f, 1.0f, 1.0f)}, + {Vector3(1.0f, -1.0f, 1.0f)}, + {Vector3(-1.0f, -1.0f, 1.0f)}, + + // botton + {Vector3(-1.0f, 1.0f, -1.0f)}, + {Vector3(1.0f, 1.0f, -1.0f)}, + {Vector3(1.0f, 1.0f, 1.0f)}, + {Vector3(1.0f, 1.0f, 1.0f)}, + {Vector3(-1.0f, 1.0f, 1.0f)}, + {Vector3(-1.0f, 1.0f, -1.0f)}, + + // top + {Vector3(-1.0f, -1.0f, -1.0f)}, + {Vector3(-1.0f, -1.0f, 1.0f)}, + {Vector3(1.0f, -1.0f, -1.0f)}, + {Vector3(1.0f, -1.0f, -1.0f)}, + {Vector3(-1.0f, -1.0f, 1.0f)}, + {Vector3(1.0f, -1.0f, 1.0f)}}; + + Dali::VertexBuffer vertexBuffer = Dali::VertexBuffer::New(Property::Map().Add("aPosition", Property::VECTOR3)); + vertexBuffer.SetData(skyboxVertices, sizeof(skyboxVertices) / sizeof(Vertex)); + + Dali::Geometry skyboxGeometry = Geometry::New(); + skyboxGeometry.AddVertexBuffer(vertexBuffer); + skyboxGeometry.SetType(Geometry::TRIANGLES); + + Dali::Shader shaderSkybox = Shader::New(SHADER_SKYBOX_SHADER_VERT.data(), SHADER_SKYBOX_SHADER_FRAG.data()); + Dali::Renderer skyboxRenderer; + skyboxRenderer = Renderer::New(skyboxGeometry, shaderSkybox); + skyboxRenderer.SetProperty(Renderer::Property::DEPTH_INDEX, 2.0f); + // Enables the depth test. + skyboxRenderer.SetProperty(Renderer::Property::DEPTH_TEST_MODE, DepthTestMode::ON); + // The fragment shader will run only is those pixels that have the max depth value. + skyboxRenderer.SetProperty(Renderer::Property::DEPTH_FUNCTION, DepthFunction::LESS_EQUAL); + + Dali::Actor skyboxActor = Actor::New(); + skyboxActor.SetProperty(Dali::Actor::Property::NAME, "SkyBox"); + skyboxActor.SetProperty(Dali::Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER); + skyboxActor.SetProperty(Dali::Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER); + skyboxActor.AddRenderer(skyboxRenderer); + return skyboxActor; +} } // anonymous namespace SceneView::SceneView() -: Control(ControlBehaviour(CONTROL_BEHAVIOUR_DEFAULT)) +: Control(ControlBehaviour(CONTROL_BEHAVIOUR_DEFAULT)), + mWindowOrientation(DEFAULT_ORIENTATION), + mSkybox(), + mSkyboxOrientation(Quaternion()), + mSkyboxIntensity(1.0f) { } -SceneView::~SceneView() = default; +SceneView::~SceneView() +{ + if(Dali::Adaptor::IsAvailable()) + { + if(mIblDiffuseLoadTask) + { + Dali::AsyncTaskManager::Get().RemoveTask(mIblDiffuseLoadTask); + mIblDiffuseLoadTask.Reset(); + } + if(mIblSpecularLoadTask) + { + Dali::AsyncTaskManager::Get().RemoveTask(mIblSpecularLoadTask); + mIblSpecularLoadTask.Reset(); + } + if(mSkyboxLoadTask) + { + Dali::AsyncTaskManager::Get().RemoveTask(mSkyboxLoadTask); + mSkyboxLoadTask.Reset(); + } + } +} Dali::Scene3D::SceneView SceneView::New() { @@ -118,17 +232,17 @@ void SceneView::RemoveCamera(CameraActor camera) } } -uint32_t SceneView::GetCameraCount() +uint32_t SceneView::GetCameraCount() const { return mCameras.size(); } -CameraActor SceneView::GetSelectedCamera() +CameraActor SceneView::GetSelectedCamera() const { return mSelectedCamera; } -CameraActor SceneView::GetCamera(uint32_t index) +CameraActor SceneView::GetCamera(uint32_t index) const { if(index < mCameras.size()) { @@ -138,7 +252,7 @@ CameraActor SceneView::GetCamera(uint32_t index) return CameraActor(); } -CameraActor SceneView::GetCamera(const std::string& name) +CameraActor SceneView::GetCamera(const std::string& name) const { CameraActor returnCamera; for(auto&& camera : mCameras) @@ -162,54 +276,142 @@ void SceneView::SelectCamera(const std::string& name) UpdateCamera(GetCamera(name)); } -void SceneView::RegisterModelView(Scene3D::ModelView modelView) +void SceneView::RegisterSceneItem(Scene3D::Internal::ImageBasedLightObserver* item) { - if(modelView) + if(item) { - modelView.SetImageBasedLightTexture(mDiffuseTexture, mSpecularTexture, mIblScaleFactor); - mModels.push_back(modelView); + item->NotifyImageBasedLightTexture(mDiffuseTexture, mSpecularTexture, mIblScaleFactor); + mItems.push_back(item); } } -void SceneView::UnregisterModelView(Scene3D::ModelView modelView) +void SceneView::UnregisterSceneItem(Scene3D::Internal::ImageBasedLightObserver* item) { - if(modelView) + if(item) { - for(uint32_t i = 0; i < mModels.size(); ++i) + for(uint32_t i = 0; i < mItems.size(); ++i) { - if(mModels[i] == modelView) + if(mItems[i] == item) { - mModels.erase(mModels.begin() + i); + mItems.erase(mItems.begin() + i); break; } } } } -void SceneView::SetImageBasedLightSource(const std::string& diffuse, const std::string& specular, float scaleFactor) +void SceneView::SetImageBasedLightSource(const std::string& diffuseUrl, const std::string& specularUrl, float scaleFactor) { - mIBLResourceReady = false; - Texture diffuseTexture = Dali::Scene3D::Loader::LoadCubeMap(diffuse); - if(diffuseTexture) + bool needIblReset = false; + bool isOnScene = Self().GetProperty(Dali::Actor::Property::CONNECTED_TO_SCENE); + if(mDiffuseIblUrl != diffuseUrl) + { + mDiffuseIblUrl = diffuseUrl; + if(mDiffuseIblUrl.empty()) + { + needIblReset = true; + } + else + { + mIblDiffuseDirty = true; + mIblDiffuseResourceReady = false; + } + } + + if(mSpecularIblUrl != specularUrl) + { + mSpecularIblUrl = specularUrl; + if(mSpecularIblUrl.empty()) + { + needIblReset = true; + } + else + { + mIblSpecularDirty = true; + mIblSpecularResourceReady = false; + } + } + + // If one or both of diffuse url and specular url are empty, + // we don't need to request to load texture. + if(needIblReset) { - Texture specularTexture = Dali::Scene3D::Loader::LoadCubeMap(specular); - if(specularTexture) + if(mIblDiffuseLoadTask) + { + Dali::AsyncTaskManager::Get().RemoveTask(mIblDiffuseLoadTask); + mIblDiffuseLoadTask.Reset(); + } + + if(mIblSpecularLoadTask) { - mDiffuseTexture = diffuseTexture; - mSpecularTexture = specularTexture; - mIblScaleFactor = scaleFactor; + Dali::AsyncTaskManager::Get().RemoveTask(mIblSpecularLoadTask); + mIblSpecularLoadTask.Reset(); + } + + mIblDiffuseDirty = false; + mIblSpecularDirty = false; + mIblDiffuseResourceReady = true; + mIblSpecularResourceReady = true; - for(auto&& model : mModels) + mDiffuseTexture.Reset(); + mSpecularTexture.Reset(); + + NotifyImageBasedLightTextureChange(); + } + else + { + if(isOnScene && mIblDiffuseDirty) + { + if(mIblDiffuseLoadTask) { - if(model) - { - model.SetImageBasedLightTexture(mDiffuseTexture, mSpecularTexture, mIblScaleFactor); - } + Dali::AsyncTaskManager::Get().RemoveTask(mIblDiffuseLoadTask); + mIblDiffuseLoadTask.Reset(); } + mIblDiffuseLoadTask = new EnvironmentMapLoadTask(mDiffuseIblUrl, MakeCallback(this, &SceneView::OnIblDiffuseLoadComplete)); + Dali::AsyncTaskManager::Get().AddTask(mIblDiffuseLoadTask); + mIblDiffuseDirty = false; + } + + if(isOnScene && mIblSpecularDirty) + { + if(mIblSpecularLoadTask) + { + Dali::AsyncTaskManager::Get().RemoveTask(mIblSpecularLoadTask); + mIblSpecularLoadTask.Reset(); + } + mIblSpecularLoadTask = new EnvironmentMapLoadTask(mSpecularIblUrl, MakeCallback(this, &SceneView::OnIblSpecularLoadComplete)); + Dali::AsyncTaskManager::Get().AddTask(mIblSpecularLoadTask); + mIblSpecularDirty = false; + } + } + + if(!Dali::Equals(mIblScaleFactor, scaleFactor)) + { + SetImageBasedLightScaleFactor(scaleFactor); + } + + // If diffuse and specular textures are already loaded, emits resource ready signal here. + if(IsResourceReady()) + { + Control::SetResourceReady(false); + } +} + +void SceneView::SetImageBasedLightScaleFactor(float scaleFactor) +{ + mIblScaleFactor = scaleFactor; + for(auto&& item : mItems) + { + if(item) + { + item->NotifyImageBasedLightScaleFactor(scaleFactor); } } - mIBLResourceReady = true; - Control::SetResourceReady(false); +} + +float SceneView::GetImageBasedLightScaleFactor() const +{ + return mIblScaleFactor; } void SceneView::UseFramebuffer(bool useFramebuffer) @@ -221,11 +423,104 @@ void SceneView::UseFramebuffer(bool useFramebuffer) } } -bool SceneView::IsUsingFramebuffer() +bool SceneView::IsUsingFramebuffer() const { return mUseFrameBuffer; } +void SceneView::SetSkybox(const std::string& skyboxUrl, Scene3D::SceneView::SkyboxType skyboxType) +{ + mSkyboxEnvironmentMapType = skyboxType; + bool isOnScene = Self().GetProperty(Dali::Actor::Property::CONNECTED_TO_SCENE); + if(mSkyboxUrl != skyboxUrl) + { + mSkyboxDirty = true; + mSkyboxResourceReady = false; + mSkyboxUrl = skyboxUrl; + } + + if(mSkyboxUrl.empty()) + { + if(mSkyboxLoadTask) + { + Dali::AsyncTaskManager::Get().RemoveTask(mSkyboxLoadTask); + mSkyboxLoadTask.Reset(); + } + if(mSkyboxImageLoader) + { + mSkyboxImageLoader.Cancel(mSkyboxImageId); + } + mSkyboxDirty = false; + mSkyboxResourceReady = true; + } + else + { + if(isOnScene && mSkyboxDirty) + { + if(mSkyboxLoadTask) + { + Dali::AsyncTaskManager::Get().RemoveTask(mSkyboxLoadTask); + mSkyboxLoadTask.Reset(); + } + if(mSkyboxImageLoader) + { + mSkyboxImageLoader.Cancel(mSkyboxImageId); + } + if(mSkyboxEnvironmentMapType == Scene3D::SceneView::SkyboxType::CUBEMAP) + { + mSkyboxLoadTask = new EnvironmentMapLoadTask(mSkyboxUrl, MakeCallback(this, &SceneView::OnSkyboxLoadComplete)); + Dali::AsyncTaskManager::Get().AddTask(mSkyboxLoadTask); + } + else + { + mSkyboxImageLoader = Dali::Toolkit::AsyncImageLoader::New(); + mSkyboxImageLoader.ImageLoadedSignal().Connect(this, &SceneView::OnSkyboxEquirectangularLoadComplete); + mSkyboxImageId = mSkyboxImageLoader.Load(mSkyboxUrl); + } + mSkyboxDirty = false; + } + } + + if(IsResourceReady()) + { + Control::SetResourceReady(false); + } +} + +void SceneView::SetSkyboxIntensity(float intensity) +{ + mSkyboxIntensity = intensity; + if(intensity < 0) + { + DALI_LOG_ERROR("Intensity should be greater than or equal to 0.\n"); + mSkyboxIntensity = 0.0f; + } + + if(mSkybox) + { + mSkybox.RegisterProperty(SKYBOX_INTENSITY_STRING.data(), mSkyboxIntensity); + } +} + +float SceneView::GetSkyboxIntensity() const +{ + return mSkyboxIntensity; +} + +void SceneView::SetSkyboxOrientation(const Quaternion& orientation) +{ + mSkyboxOrientation = orientation; + if(mSkybox) + { + mSkybox.SetProperty(Dali::Actor::Property::ORIENTATION, orientation); + } +} + +Quaternion SceneView::GetSkyboxOrientation() const +{ + return mSkyboxOrientation; +} + /////////////////////////////////////////////////////////// // // Private methods @@ -233,14 +528,53 @@ bool SceneView::IsUsingFramebuffer() void SceneView::OnSceneConnection(int depth) { - UpdateRenderTask(); + // If diffuse and specular url is not valid, IBL does not need to be loaded. + if(!mDiffuseIblUrl.empty() && !mSpecularIblUrl.empty()) + { + SetImageBasedLightSource(mDiffuseIblUrl, mSpecularIblUrl, mIblScaleFactor); + } + + if(!mSkyboxUrl.empty()) + { + SetSkybox(mSkyboxUrl, mSkyboxEnvironmentMapType); + } + + Window window = DevelWindow::Get(Self()); + if(window) + { + window.ResizeSignal().Connect(this, &SceneView::OnWindowResized); + RenderTaskList taskList = window.GetRenderTaskList(); + mRenderTask = taskList.CreateTask(); + mRenderTask.SetSourceActor(mRootLayer); + mRenderTask.SetExclusive(true); + mRenderTask.SetInputEnabled(true); + mRenderTask.SetCullMode(false); + mRenderTask.SetScreenToFrameBufferMappingActor(Self()); + + UpdateRenderTask(); + mWindow = window; + } Control::OnSceneConnection(depth); } void SceneView::OnSceneDisconnection() { - mModels.clear(); + mItems.clear(); + + Window window = mWindow.GetHandle(); + if(window) + { + window.ResizeSignal().Disconnect(this, &SceneView::OnWindowResized); + RenderTaskList taskList = window.GetRenderTaskList(); + if(mRenderTask) + { + taskList.RemoveTask(mRenderTask); + mFrameBuffer.Reset(); + } + } + mWindow.Reset(); + Control::OnSceneDisconnection(); } @@ -256,14 +590,6 @@ void SceneView::OnInitialize() mRootLayer.SetProperty(Dali::Actor::Property::INHERIT_SCALE, false); self.Add(mRootLayer); - RenderTaskList taskList = Stage::GetCurrent().GetRenderTaskList(); - mRenderTask = taskList.CreateTask(); - mRenderTask.SetSourceActor(mRootLayer); - mRenderTask.SetExclusive(true); - mRenderTask.SetInputEnabled(true); - mRenderTask.SetCullMode(false); - mRenderTask.SetScreenToFrameBufferMappingActor(Self()); - mDefaultCamera = Dali::CameraActor::New(); mDefaultCamera.SetProperty(Dali::Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER); mDefaultCamera.SetProperty(Dali::Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER); @@ -310,7 +636,7 @@ void SceneView::OnRelayout(const Vector2& size, RelayoutContainer& container) bool SceneView::IsResourceReady() const { - return mIBLResourceReady; + return mIblDiffuseResourceReady && mIblSpecularResourceReady && mSkyboxResourceReady; } void SceneView::UpdateCamera(CameraActor camera) @@ -337,41 +663,47 @@ void SceneView::UpdateRenderTask() mRenderTask.SetCameraActor(mSelectedCamera); } - Vector3 size = Self().GetProperty(Dali::Actor::Property::SIZE); + Vector3 size = Self().GetProperty(Dali::Actor::Property::SIZE); const float aspectRatio = size.width / size.height; mSelectedCamera.SetAspectRatio(aspectRatio); - const float halfHeight = mSelectedCamera[Dali::CameraActor::Property::TOP_PLANE_DISTANCE]; - const float halfWidth = aspectRatio * halfHeight; - mSelectedCamera[Dali::CameraActor::Property::LEFT_PLANE_DISTANCE] = -halfWidth; - mSelectedCamera[Dali::CameraActor::Property::RIGHT_PLANE_DISTANCE] = halfWidth; - mSelectedCamera[Dali::CameraActor::Property::TOP_PLANE_DISTANCE] = halfHeight; // Top is +ve to keep consistency with orthographic values - mSelectedCamera[Dali::CameraActor::Property::BOTTOM_PLANE_DISTANCE] = -halfHeight; // Bottom is -ve to keep consistency with orthographic values + if(mUseFrameBuffer) { Dali::FrameBuffer currentFrameBuffer = mRenderTask.GetFrameBuffer(); if(!currentFrameBuffer || - currentFrameBuffer.GetColorTexture().GetWidth() != size.width || - currentFrameBuffer.GetColorTexture().GetHeight() != size.height) + !Dali::Equals(currentFrameBuffer.GetColorTexture().GetWidth(), size.width) || + !Dali::Equals(currentFrameBuffer.GetColorTexture().GetHeight(), size.height)) { + mRootLayer.SetProperty(Dali::Actor::Property::COLOR_MODE, ColorMode::USE_OWN_COLOR); mRenderTask.ResetViewportGuideActor(); mRenderTask.SetViewport(Dali::Viewport(Vector4::ZERO)); // create offscreen buffer of new size to render our child actors to - mTexture = Dali::Texture::New(TextureType::TEXTURE_2D, Pixel::RGBA8888, unsigned(size.width), unsigned(size.height)); - mRenderTarget = FrameBuffer::New(size.width, size.height, FrameBuffer::Attachment::DEPTH_STENCIL); - mRenderTarget.AttachColorTexture(mTexture); - Dali::Toolkit::ImageUrl imageUrl = Dali::Toolkit::Image::GenerateUrl(mRenderTarget, 0u); + mTexture = Dali::Texture::New(TextureType::TEXTURE_2D, Pixel::RGBA8888, unsigned(size.width), unsigned(size.height)); + mFrameBuffer = FrameBuffer::New(size.width, size.height, FrameBuffer::Attachment::DEPTH_STENCIL); + mFrameBuffer.AttachColorTexture(mTexture); + DevelFrameBuffer::SetMultiSamplingLevel(mFrameBuffer, DEFAULT_FRAME_BUFFER_MULTI_SAMPLING_LEVEL); + Dali::Toolkit::ImageUrl imageUrl = Dali::Toolkit::Image::GenerateUrl(mFrameBuffer, 0u); Property::Map imagePropertyMap; imagePropertyMap.Insert(Toolkit::Visual::Property::TYPE, Toolkit::Visual::IMAGE); imagePropertyMap.Insert(Toolkit::ImageVisual::Property::URL, imageUrl.GetUrl()); + // To make sure this visual call LoadTexture API immediate. + imagePropertyMap.Insert(Toolkit::ImageVisual::Property::LOAD_POLICY, Toolkit::ImageVisual::LoadPolicy::IMMEDIATE); + imagePropertyMap.Insert(Toolkit::ImageVisual::Property::RELEASE_POLICY, Toolkit::ImageVisual::ReleasePolicy::DESTROYED); // To flip rendered scene without CameraActor::SetInvertYAxis() to avoid backface culling. imagePropertyMap.Insert(Toolkit::ImageVisual::Property::PIXEL_AREA, Vector4(0.0f, 1.0f, 1.0f, -1.0f)); mVisual = Toolkit::VisualFactory::Get().CreateVisual(imagePropertyMap); + // Use premultiplied alpha when we use FBO + if(mVisual) + { + Toolkit::GetImplementation(mVisual).EnablePreMultipliedAlpha(true); + } + Toolkit::DevelControl::RegisterVisual(*this, RENDERING_BUFFER, mVisual); - mRenderTask.SetFrameBuffer(mRenderTarget); + mRenderTask.SetFrameBuffer(mFrameBuffer); mRenderTask.SetClearEnabled(true); mRenderTask.SetClearColor(Color::TRANSPARENT); } @@ -381,11 +713,129 @@ void SceneView::UpdateRenderTask() mRenderTask.SetViewportGuideActor(Self()); if(mRenderTask.GetFrameBuffer()) { + mRootLayer.SetProperty(Dali::Actor::Property::COLOR_MODE, ColorMode::USE_OWN_MULTIPLY_PARENT_ALPHA); FrameBuffer framebuffer; mRenderTask.SetFrameBuffer(framebuffer); mRenderTask.SetClearEnabled(false); + + Toolkit::DevelControl::UnregisterVisual(*this, RENDERING_BUFFER); + + mVisual.Reset(); + mFrameBuffer.Reset(); + mTexture.Reset(); } } + + RotateCamera(); + } +} + +void SceneView::OnWindowResized(Window window, Window::WindowSize size) +{ + mWindowOrientation = DevelWindow::GetPhysicalOrientation(window); + RotateCamera(); +} + +void SceneView::RotateCamera() +{ + if(mUseFrameBuffer) + { + DevelCameraActor::RotateProjection(mSelectedCamera, DEFAULT_ORIENTATION); + } + else + { + DevelCameraActor::RotateProjection(mSelectedCamera, mWindowOrientation); + } +} + +void SceneView::OnSkyboxEquirectangularLoadComplete(uint32_t loadedTaskId, PixelData pixelData) +{ + mSkyboxTexture = Texture::New(TextureType::TEXTURE_2D, pixelData.GetPixelFormat(), pixelData.GetWidth(), pixelData.GetHeight()); + mSkyboxTexture.Upload(pixelData, 0, 0, 0, 0, pixelData.GetWidth(), pixelData.GetHeight()); + OnSkyboxLoadComplete(); +} + +void SceneView::OnSkyboxLoadComplete() +{ + if(!mSkybox) + { + mSkybox = CreateSkybox(); + SetSkyboxIntensity(mSkyboxIntensity); + SetSkyboxOrientation(mSkyboxOrientation); + if(mRootLayer) + { + mRootLayer.Add(mSkybox); + } + } + + mSkyboxResourceReady = true; + if(IsResourceReady()) + { + Control::SetResourceReady(false); + } + + Shader skyboxShader; + if(mSkyboxEnvironmentMapType == Scene3D::SceneView::SkyboxType::CUBEMAP) + { + mSkyboxTexture = (mSkyboxLoadTask->HasSucceeded()) ? mSkyboxLoadTask->GetEnvironmentMap().CreateTexture() : Texture(); + skyboxShader = Shader::New(SHADER_SKYBOX_SHADER_VERT.data(), SHADER_SKYBOX_SHADER_FRAG.data()); + Dali::AsyncTaskManager::Get().RemoveTask(mSkyboxLoadTask); + mSkyboxLoadTask.Reset(); + } + else + { + skyboxShader = Shader::New(SHADER_SKYBOX_SHADER_VERT.data(), SHADER_SKYBOX_EQUIRECTANGULAR_SHADER_FRAG.data()); + } + + Renderer skyboxRenderer = (mSkybox.GetRendererCount() > 0u) ? mSkybox.GetRendererAt(0u) : Renderer(); + if(skyboxRenderer) + { + Dali::TextureSet skyboxTextures = TextureSet::New(); + skyboxTextures.SetTexture(0, mSkyboxTexture); + skyboxRenderer.SetTextures(skyboxTextures); + skyboxRenderer.SetShader(skyboxShader); + } +} + +void SceneView::OnIblDiffuseLoadComplete() +{ + mDiffuseTexture = (mIblDiffuseLoadTask->HasSucceeded()) ? mIblDiffuseLoadTask->GetEnvironmentMap().CreateTexture() : Texture(); + mIblDiffuseResourceReady = true; + if(mIblDiffuseResourceReady && mIblSpecularResourceReady) + { + OnIblLoadComplete(); + } + mIblDiffuseLoadTask.Reset(); +} + +void SceneView::OnIblSpecularLoadComplete() +{ + mSpecularTexture = (mIblSpecularLoadTask->HasSucceeded()) ? mIblSpecularLoadTask->GetEnvironmentMap().CreateTexture() : Texture(); + mIblSpecularResourceReady = true; + if(mIblDiffuseResourceReady && mIblSpecularResourceReady) + { + OnIblLoadComplete(); + } + mIblSpecularLoadTask.Reset(); +} + +void SceneView::OnIblLoadComplete() +{ + NotifyImageBasedLightTextureChange(); + if(IsResourceReady()) + { + Control::SetResourceReady(false); + } +} + +void SceneView::NotifyImageBasedLightTextureChange() +{ + for(auto&& item : mItems) + { + if(item) + { + item->NotifyImageBasedLightTexture(mDiffuseTexture, mSpecularTexture, mIblScaleFactor); + } } }