X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dali-scene3d%2Finternal%2Fcontrols%2Fscene-view%2Fscene-view-impl.cpp;h=f4d549823e21efb642883ba293c763590381e969;hb=6b3a4233336af0f8b1949246ddc45bc3f8219e4f;hp=f0afd0d65d57963a50f90a7bfd64f39214d20ccd;hpb=c3fca0844bdad8df8008e23b08ddbf409f9932c2;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 f0afd0d..f4d5498 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,21 @@ #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,12 +59,122 @@ 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(const std::string& skyboxUrl, Scene3D::SceneView::SkyboxType skyboxType) +{ + 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::Texture skyboxTexture; + Dali::Shader shaderSkybox; + Dali::Renderer skyboxRenderer; + + if(skyboxType == Scene3D::SceneView::SkyboxType::CUBEMAP) + { + skyboxTexture = Dali::Scene3D::Loader::LoadCubeMap(skyboxUrl); + shaderSkybox = Shader::New(SHADER_SKYBOX_SHADER_VERT.data(), SHADER_SKYBOX_SHADER_FRAG.data()); + } + else // Scene3D::SceneView::SkyboxType::EQUIRECTANGULAR + { + // Load image from file + PixelData pixels = Dali::Toolkit::SyncImageLoader::Load(skyboxUrl); + + skyboxTexture = Texture::New(TextureType::TEXTURE_2D, pixels.GetPixelFormat(), pixels.GetWidth(), pixels.GetHeight()); + skyboxTexture.Upload(pixels, 0, 0, 0, 0, pixels.GetWidth(), pixels.GetHeight()); + shaderSkybox = Shader::New(SHADER_SKYBOX_SHADER_VERT.data(), SHADER_SKYBOX_EQUIRECTANGULAR_SHADER_FRAG.data()); + } + + Dali::TextureSet skyboxTextures = TextureSet::New(); + skyboxTextures.SetTexture(0, skyboxTexture); + + skyboxRenderer = Renderer::New(skyboxGeometry, shaderSkybox); + skyboxRenderer.SetTextures(skyboxTextures); + 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) { } @@ -162,64 +276,63 @@ 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) + + // If url is empty or invalid, reset IBL. + mDiffuseTexture = (!diffuseUrl.empty()) ? Dali::Scene3D::Loader::LoadCubeMap(diffuseUrl) : Texture(); + mSpecularTexture = (!specularUrl.empty()) ? Dali::Scene3D::Loader::LoadCubeMap(specularUrl) : Texture(); + + mIblScaleFactor = scaleFactor; + + for(auto&& item : mItems) { - Texture specularTexture = Dali::Scene3D::Loader::LoadCubeMap(specular); - if(specularTexture) + if(item) { - mDiffuseTexture = diffuseTexture; - mSpecularTexture = specularTexture; - mIblScaleFactor = scaleFactor; - - for(auto&& model : mModels) - { - if(model) - { - model.SetImageBasedLightTexture(mDiffuseTexture, mSpecularTexture, mIblScaleFactor); - } - } + item->NotifyImageBasedLightTexture(mDiffuseTexture, mSpecularTexture, mIblScaleFactor); } } + mIBLResourceReady = true; - Control::SetResourceReady(false); + if(IsResourceReady()) + { + Control::SetResourceReady(false); + } } void SceneView::SetImageBasedLightScaleFactor(float scaleFactor) { mIblScaleFactor = scaleFactor; - for(auto&& model : mModels) + for(auto&& item : mItems) { - if(model) + if(item) { - model.SetImageBasedLightScaleFactor(scaleFactor); + item->NotifyImageBasedLightScaleFactor(scaleFactor); } } } @@ -243,6 +356,63 @@ bool SceneView::IsUsingFramebuffer() const return mUseFrameBuffer; } +void SceneView::SetSkybox(const std::string& skyboxUrl, Scene3D::SceneView::SkyboxType skyboxType) +{ + mSkyboxResourceReady = false; + if(mSkybox) + { + mSkybox.Unparent(); + mSkybox.Reset(); + } + mSkybox = CreateSkybox(skyboxUrl, skyboxType); + SetSkyboxIntensity(mSkyboxIntensity); + SetSkyboxOrientation(mSkyboxOrientation); + if(mRootLayer) + { + mRootLayer.Add(mSkybox); + } + + mSkyboxResourceReady = true; + 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 @@ -250,14 +420,42 @@ bool SceneView::IsUsingFramebuffer() const void SceneView::OnSceneConnection(int depth) { - UpdateRenderTask(); + 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(); } @@ -273,14 +471,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); @@ -327,7 +517,7 @@ void SceneView::OnRelayout(const Vector2& size, RelayoutContainer& container) bool SceneView::IsResourceReady() const { - return mIBLResourceReady; + return mIBLResourceReady & mSkyboxResourceReady; } void SceneView::UpdateCamera(CameraActor camera) @@ -354,15 +544,10 @@ 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(); @@ -374,10 +559,11 @@ void SceneView::UpdateRenderTask() 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); @@ -388,7 +574,7 @@ void SceneView::UpdateRenderTask() Toolkit::DevelControl::RegisterVisual(*this, RENDERING_BUFFER, mVisual); - mRenderTask.SetFrameBuffer(mRenderTarget); + mRenderTask.SetFrameBuffer(mFrameBuffer); mRenderTask.SetClearEnabled(true); mRenderTask.SetClearColor(Color::TRANSPARENT); } @@ -401,8 +587,34 @@ void SceneView::UpdateRenderTask() 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); } }