Commit 8d0c87d1f4ecdbafa9f9882d6708e82b22d19807
Committed by
Gerrit Code Review
Merge "SceneViewTest demo use SetResolution / ModelNode's Material" into devel/master
Showing
7 changed files
with
589 additions
and
2 deletions
examples/scene-view-test/README.md
0 → 100644
| 1 | +# Scene View Test Example | |
| 2 | + | |
| 3 | +This is a various test example for SceneView and Model API in the DALi Scene3D library. | |
| 4 | + | |
| 5 | + - Use Framebuffer instead of direct rendering | |
| 6 | + - Framebuffer multi samping level (Works only Framebuffer used) | |
| 7 | + - Resolution of target (Works only Framebuffer used) | |
| 8 | + - Screen extents calculation and show the result | |
| 9 | + - Focus change by keyboard + touch | |
| 10 | + - Change material property | |
| 11 | + | |
| 12 | +Please update this note if you add some more test cases. | |
| 13 | + | |
| 14 | + | ... | ... |
examples/scene-view-test/scene-view-test-example.cpp
0 → 100644
| 1 | +/* | |
| 2 | + * Copyright (c) 2024 Samsung Electronics Co., Ltd. | |
| 3 | + * | |
| 4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | |
| 5 | + * you may not use this file except in compliance with the License. | |
| 6 | + * You may obtain a copy of the License at | |
| 7 | + * | |
| 8 | + * http://www.apache.org/licenses/LICENSE-2.0 | |
| 9 | + * | |
| 10 | + * Unless required by applicable law or agreed to in writing, software | |
| 11 | + * distributed under the License is distributed on an "AS IS" BASIS, | |
| 12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| 13 | + * See the License for the specific language governing permissions and | |
| 14 | + * limitations under the License. | |
| 15 | + * | |
| 16 | + */ | |
| 17 | + | |
| 18 | +// EXTERNAL INCLUDES | |
| 19 | +#include <dali-scene3d/dali-scene3d.h> | |
| 20 | +#include <dali-toolkit/dali-toolkit.h> | |
| 21 | + | |
| 22 | +#include <dali-toolkit/devel-api/focus-manager/keyboard-focus-manager-devel.h> | |
| 23 | +#include <dali/devel-api/actors/actor-devel.h> | |
| 24 | + | |
| 25 | +// INTERNAL INCLUDES | |
| 26 | +#include <dali/devel-api/adaptor-framework/file-stream.h> | |
| 27 | + | |
| 28 | +using namespace Dali; | |
| 29 | +using namespace Toolkit; | |
| 30 | +using namespace Scene3D; | |
| 31 | + | |
| 32 | +namespace | |
| 33 | +{ | |
| 34 | +const char* CUBEMAP_SKY_BOX_URL = DEMO_IMAGE_DIR "veste_oberhaus_cubemap.png"; | |
| 35 | +const char* CUBEMAP_IRRADIANCE_URL = DEMO_IMAGE_DIR "veste_oberhaus_irradiance.png"; | |
| 36 | +const char* CAMERA_NAME("MyCamera"); | |
| 37 | + | |
| 38 | +const char* MODEL_URL = DEMO_MODEL_DIR "SphereMetallic.gltf"; | |
| 39 | +constexpr Vector3 MODEL_SIZE(300.0f, 300.0f, 300.0f); | |
| 40 | +const char* SUB_MODEL_URL = DEMO_MODEL_DIR "Duck.gltf"; | |
| 41 | +constexpr Vector3 SUB_MODEL_SIZE(300.0f, 300.0f, 300.0f); | |
| 42 | +constexpr Vector3 SUB_MODEL_SCALE(1.2f, 0.6f, 1.0f); | |
| 43 | + | |
| 44 | +constexpr Vector4 ORIGINAL_BASE_COLOR_FACTOR(0.6039215686274509f, 0.6039215686274509f, 0.6039215686274509f, 1.0f); | |
| 45 | +constexpr Vector3 ORIGINAL_EMISSIVE_FACTOR(0.0f, 0.0f, 0.0f); | |
| 46 | +constexpr float ORIGINAL_METALLIC_FACTOR(1.0f); | |
| 47 | +constexpr float ORIGINAL_ROUGHNESS_FACTOR(0.0f); | |
| 48 | + | |
| 49 | +constexpr Vector4 ORIGINAL_SUB_BASE_COLOR_FACTOR(1.0f, 1.0f, 1.0f, 1.0f); | |
| 50 | +constexpr Vector3 ORIGINAL_SUB_EMISSIVE_FACTOR(0.0f, 0.0f, 0.0f); | |
| 51 | +constexpr float ORIGINAL_SUB_METALLIC_FACTOR(0.0f); | |
| 52 | +constexpr float ORIGINAL_SUB_ROUGHNESS_FACTOR(1.0f); | |
| 53 | + | |
| 54 | +constexpr Vector4 FOCUSED_BASE_COLOR_FACTOR(1.0f, 1.0f, 1.0f, 1.0f); | |
| 55 | +constexpr Vector3 FOCUSED_EMISSIVE_FACTOR(0.1f, 0.0f, 0.0f); | |
| 56 | +constexpr float FOCUSED_METALLIC_FACTOR(0.2f); | |
| 57 | +constexpr float FOCUSED_ROUGHNESS_FACTOR(0.5f); | |
| 58 | + | |
| 59 | +constexpr uint8_t FRAMEBUFFER_MULTI_SAMPLING_LEVEL = 4u; | |
| 60 | + | |
| 61 | +constexpr uint32_t MAX_BACKLOG_COUNT = 10; | |
| 62 | + | |
| 63 | +constexpr float RESOLUTION_RATE_DOWNSCALED = 0.25f; | |
| 64 | +constexpr float RESOLUTION_RATE_UPSCALED = 1.5f; | |
| 65 | +constexpr float RESOLUTION_RATE_OVER_DOWNSCALED = 0.1f; | |
| 66 | +constexpr float RESOLUTION_RATE_OVER_UPSCALED = 2.5f; | |
| 67 | + | |
| 68 | +const Quaternion MODEL_ROTATION(Degree(360.f), Vector3(0.1f, 1.0f, -0.1f)); | |
| 69 | + | |
| 70 | +enum ResolutionType | |
| 71 | +{ | |
| 72 | + DEFAULT = 0, | |
| 73 | + DOWNSCALED, | |
| 74 | + UPSCALED, | |
| 75 | + | |
| 76 | + OVER_DOWNSCALED, | |
| 77 | + OVER_UPSCALED, | |
| 78 | + | |
| 79 | + MAX, | |
| 80 | +}; | |
| 81 | + | |
| 82 | +void ApplyAllMaterialPropertyRecursively(Scene3D::ModelNode modelNode, const std::vector<KeyValuePair>& materialPropertyValues) | |
| 83 | +{ | |
| 84 | + if(!modelNode) | |
| 85 | + { | |
| 86 | + return; | |
| 87 | + } | |
| 88 | + | |
| 89 | + for(uint32_t primitiveIndex = 0u; primitiveIndex < modelNode.GetModelPrimitiveCount(); ++primitiveIndex) | |
| 90 | + { | |
| 91 | + Scene3D::ModelPrimitive primitive = modelNode.GetModelPrimitive(primitiveIndex); | |
| 92 | + if(primitive) | |
| 93 | + { | |
| 94 | + Scene3D::Material material = primitive.GetMaterial(); | |
| 95 | + if(material) | |
| 96 | + { | |
| 97 | + for(const auto& keyValuePair : materialPropertyValues) | |
| 98 | + { | |
| 99 | + if(keyValuePair.first.type == Property::Key::Type::INDEX) | |
| 100 | + { | |
| 101 | + material.SetProperty(keyValuePair.first.indexKey, keyValuePair.second); | |
| 102 | + } | |
| 103 | + } | |
| 104 | + } | |
| 105 | + } | |
| 106 | + } | |
| 107 | + | |
| 108 | + for(uint32_t childIndex = 0u; childIndex < modelNode.GetChildCount(); ++childIndex) | |
| 109 | + { | |
| 110 | + Scene3D::ModelNode childNode = Scene3D::ModelNode::DownCast(modelNode.GetChildAt(childIndex)); | |
| 111 | + ApplyAllMaterialPropertyRecursively(childNode, materialPropertyValues); | |
| 112 | + } | |
| 113 | +} | |
| 114 | + | |
| 115 | +} // namespace | |
| 116 | + | |
| 117 | +class SceneViewExample : public ConnectionTracker | |
| 118 | +{ | |
| 119 | +public: | |
| 120 | + SceneViewExample(Application& application) | |
| 121 | + : mApplication(application) | |
| 122 | + { | |
| 123 | + // Connect to the Application's Init signal | |
| 124 | + mApplication.InitSignal().Connect(this, &SceneViewExample::Create); | |
| 125 | + } | |
| 126 | + | |
| 127 | + ~SceneViewExample() = default; | |
| 128 | + | |
| 129 | +private: | |
| 130 | + // The Init signal is received once (only) during the Application lifetime | |
| 131 | + void Create(Application& application) | |
| 132 | + { | |
| 133 | + // Get a handle to the window | |
| 134 | + mWindow = application.GetWindow(); | |
| 135 | + const Vector2 windowSize = mWindow.GetSize(); | |
| 136 | + | |
| 137 | + // Create a SceneView and set the Skybox | |
| 138 | + mSceneView = Handle::New<SceneView>({{Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER}, | |
| 139 | + {Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER}, | |
| 140 | + {Actor::Property::SIZE, windowSize}}); | |
| 141 | + mSceneView.SetSkybox(CUBEMAP_SKY_BOX_URL); | |
| 142 | + mWindow.Add(mSceneView); | |
| 143 | + | |
| 144 | + // Load the model and set IBL | |
| 145 | + mMainModel = Model::New(MODEL_URL); | |
| 146 | + mMainModel.SetProperties({ | |
| 147 | + {Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER}, | |
| 148 | + {Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER}, | |
| 149 | + {Actor::Property::POSITION, Vector3::ZERO}, | |
| 150 | + {Actor::Property::SIZE, MODEL_SIZE}, | |
| 151 | + {Actor::Property::NAME, "MainModel"}, | |
| 152 | + {Actor::Property::KEYBOARD_FOCUSABLE, true}, | |
| 153 | + {DevelActor::Property::TOUCH_FOCUSABLE, true}, | |
| 154 | + }); | |
| 155 | + mMainModel.SetImageBasedLightSource(CUBEMAP_IRRADIANCE_URL, CUBEMAP_SKY_BOX_URL); | |
| 156 | + mSceneView.Add(mMainModel); | |
| 157 | + | |
| 158 | + mSubModel = Model::New(SUB_MODEL_URL); | |
| 159 | + mSubModel.SetProperties({ | |
| 160 | + {Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER}, | |
| 161 | + {Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER}, | |
| 162 | + {Actor::Property::POSITION, Vector3(MODEL_SIZE.x, MODEL_SIZE.y * 0.5f, 0.0f)}, | |
| 163 | + {Actor::Property::SIZE, SUB_MODEL_SIZE}, | |
| 164 | + {Actor::Property::SCALE, SUB_MODEL_SCALE}, | |
| 165 | + {Actor::Property::NAME, "SubModel"}, | |
| 166 | + {Actor::Property::KEYBOARD_FOCUSABLE, true}, | |
| 167 | + {DevelActor::Property::TOUCH_FOCUSABLE, true}, | |
| 168 | + }); | |
| 169 | + mSubModel.SetImageBasedLightSource(CUBEMAP_IRRADIANCE_URL, CUBEMAP_SKY_BOX_URL, 0.25f); | |
| 170 | + mSceneView.Add(mSubModel); | |
| 171 | + | |
| 172 | + // Create a new camera and reparent as we want to rotate the camera around the origin | |
| 173 | + CameraActor cameraActor = Handle::New<CameraActor>({{Actor::Property::NAME, CAMERA_NAME}}); | |
| 174 | + mSceneView.AddCamera(cameraActor); | |
| 175 | + mSceneView.SelectCamera(CAMERA_NAME); | |
| 176 | + cameraActor.SetType(Camera::LOOK_AT_TARGET); | |
| 177 | + cameraActor.SetTargetPosition(Vector3::ZERO); | |
| 178 | + cameraActor.Unparent(); | |
| 179 | + Actor rotatingActor = Handle::New<Actor>({{Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER}, | |
| 180 | + {Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER}}); | |
| 181 | + rotatingActor.Add(cameraActor); | |
| 182 | + mSceneView.Add(rotatingActor); | |
| 183 | + | |
| 184 | + mCameraRotateAnimation = Animation::New(10.0f); | |
| 185 | + mCameraRotateAnimation.SetLooping(true); | |
| 186 | + mCameraRotateAnimation.AnimateBy(Property(rotatingActor, Actor::Property::ORIENTATION), MODEL_ROTATION); | |
| 187 | + if(mRotateCamera) | |
| 188 | + { | |
| 189 | + mCameraRotateAnimation.Play(); | |
| 190 | + } | |
| 191 | + | |
| 192 | + // Respond to key events | |
| 193 | + mWindow.KeyEventSignal().Connect(this, &SceneViewExample::OnKeyEvent); | |
| 194 | + mWindow.ResizeSignal().Connect(this, &SceneViewExample::OnWindowResize); | |
| 195 | + | |
| 196 | + DevelKeyboardFocusManager::EnableDefaultAlgorithm(KeyboardFocusManager::Get(), true); | |
| 197 | + | |
| 198 | + mMainModel.KeyInputFocusGainedSignal().Connect(this, &SceneViewExample::OnFocusGained); | |
| 199 | + mMainModel.KeyInputFocusLostSignal().Connect(this, &SceneViewExample::OnFocusLost); | |
| 200 | + mSubModel.KeyInputFocusGainedSignal().Connect(this, &SceneViewExample::OnFocusGained); | |
| 201 | + mSubModel.KeyInputFocusLostSignal().Connect(this, &SceneViewExample::OnFocusLost); | |
| 202 | + KeyboardFocusManager::Get().FocusChangedSignal().Connect(this, &SceneViewExample::OnFocusChanged); | |
| 203 | + | |
| 204 | + mScreenExtentTimer = Timer::New(16); | |
| 205 | + mScreenExtentTimer.TickSignal().Connect(this, &SceneViewExample::OnTick); | |
| 206 | + if(mShowScreenExtent) | |
| 207 | + { | |
| 208 | + mScreenExtentTimer.Start(); | |
| 209 | + } | |
| 210 | + | |
| 211 | + ApplyDebugLog(); | |
| 212 | + } | |
| 213 | + | |
| 214 | + /** | |
| 215 | + * @brief Called when any key event is received | |
| 216 | + * | |
| 217 | + * Will use this to quit the application if Back or the Escape key is received | |
| 218 | + * @param[in] event The key event information | |
| 219 | + */ | |
| 220 | + void OnKeyEvent(const KeyEvent& event) | |
| 221 | + { | |
| 222 | + if(event.GetState() == KeyEvent::DOWN) | |
| 223 | + { | |
| 224 | + if(IsKey(event, Dali::DALI_KEY_ESCAPE) || IsKey(event, Dali::DALI_KEY_BACK)) | |
| 225 | + { | |
| 226 | + if(KeyboardFocusManager::Get().GetCurrentFocusActor()) | |
| 227 | + { | |
| 228 | + KeyboardFocusManager::Get().ClearFocus(); | |
| 229 | + } | |
| 230 | + else | |
| 231 | + { | |
| 232 | + mApplication.Quit(); | |
| 233 | + } | |
| 234 | + } | |
| 235 | + | |
| 236 | + if(event.GetKeyName() == "1") | |
| 237 | + { | |
| 238 | + mShowDebugLabel ^= 1; | |
| 239 | + } | |
| 240 | + else if(event.GetKeyName() == "2") | |
| 241 | + { | |
| 242 | + mUseFrameBuffer ^= 1; | |
| 243 | + if(mSceneView) | |
| 244 | + { | |
| 245 | + mSceneView.UseFramebuffer(mUseFrameBuffer); | |
| 246 | + } | |
| 247 | + } | |
| 248 | + else if(event.GetKeyName() == "3") | |
| 249 | + { | |
| 250 | + mUseFrameBufferMultiSample ^= 1; | |
| 251 | + if(mSceneView) | |
| 252 | + { | |
| 253 | + mSceneView.SetFramebufferMultiSamplingLevel(mUseFrameBufferMultiSample ? FRAMEBUFFER_MULTI_SAMPLING_LEVEL : 0); | |
| 254 | + } | |
| 255 | + } | |
| 256 | + else if(event.GetKeyName() == "4") | |
| 257 | + { | |
| 258 | + mResolutionType = static_cast<ResolutionType>(static_cast<int>(mResolutionType + 1) % ResolutionType::MAX); | |
| 259 | + ApplyResolution(); | |
| 260 | + } | |
| 261 | + else if(event.GetKeyName() == "5") | |
| 262 | + { | |
| 263 | + mRotateCamera ^= true; | |
| 264 | + if(mCameraRotateAnimation) | |
| 265 | + { | |
| 266 | + if(!mRotateCamera && mCameraRotateAnimation.GetState() == Animation::PLAYING) | |
| 267 | + { | |
| 268 | + mCameraRotateAnimation.Stop(); | |
| 269 | + } | |
| 270 | + else if(mRotateCamera && mCameraRotateAnimation.GetState() != Animation::PLAYING) | |
| 271 | + { | |
| 272 | + mCameraRotateAnimation.Play(); | |
| 273 | + } | |
| 274 | + } | |
| 275 | + } | |
| 276 | + else if(event.GetKeyName() == "6") | |
| 277 | + { | |
| 278 | + mShowScreenExtent ^= true; | |
| 279 | + if(mScreenExtentTimer) | |
| 280 | + { | |
| 281 | + if(!mShowScreenExtent && mScreenExtentTimer.IsRunning()) | |
| 282 | + { | |
| 283 | + mScreenExtentTimer.Stop(); | |
| 284 | + } | |
| 285 | + else if(mShowScreenExtent && !mScreenExtentTimer.IsRunning()) | |
| 286 | + { | |
| 287 | + mScreenExtentTimer.Start(); | |
| 288 | + } | |
| 289 | + } | |
| 290 | + if(mMainModelAABB) | |
| 291 | + { | |
| 292 | + mMainModelAABB[Actor::Property::VISIBLE] = mShowScreenExtent; | |
| 293 | + } | |
| 294 | + if(mSubModelAABB) | |
| 295 | + { | |
| 296 | + mSubModelAABB[Actor::Property::VISIBLE] = mShowScreenExtent; | |
| 297 | + } | |
| 298 | + } | |
| 299 | + ApplyDebugLog(); | |
| 300 | + } | |
| 301 | + } | |
| 302 | + | |
| 303 | + void OnWindowResize(Window window, Window::WindowSize newSize) | |
| 304 | + { | |
| 305 | + if(mSceneView) | |
| 306 | + { | |
| 307 | + mSceneView[Actor::Property::SIZE_WIDTH] = newSize.GetWidth(); | |
| 308 | + mSceneView[Actor::Property::SIZE_HEIGHT] = newSize.GetHeight(); | |
| 309 | + ApplyResolution(); | |
| 310 | + } | |
| 311 | + } | |
| 312 | + | |
| 313 | + void OnFocusChanged(Actor from, Actor to) | |
| 314 | + { | |
| 315 | + if(!from && !to) | |
| 316 | + { | |
| 317 | + return; | |
| 318 | + } | |
| 319 | + std::ostringstream oss; | |
| 320 | + oss << "Focus changed from : ["; | |
| 321 | + oss << (from ? from.GetProperty<std::string>(Actor::Property::NAME) : "(nil)"); | |
| 322 | + oss << "] -> ["; | |
| 323 | + oss << (to ? to.GetProperty<std::string>(Actor::Property::NAME) : "(nil)"); | |
| 324 | + oss << "]"; | |
| 325 | + ApplyBackLog(oss.str()); | |
| 326 | + } | |
| 327 | + | |
| 328 | + void OnFocusGained(Control control) | |
| 329 | + { | |
| 330 | + std::ostringstream oss; | |
| 331 | + oss << "Focus gained : ["; | |
| 332 | + oss << (control ? control.GetProperty<std::string>(Actor::Property::NAME) : "(nil)"); | |
| 333 | + oss << "]"; | |
| 334 | + ApplyBackLog(oss.str()); | |
| 335 | + | |
| 336 | + Model model = Model::DownCast(control); | |
| 337 | + if(model) | |
| 338 | + { | |
| 339 | + ApplyAllMaterialPropertyRecursively( | |
| 340 | + model.GetModelRoot(), | |
| 341 | + { | |
| 342 | + {Material::Property::BASE_COLOR_FACTOR, FOCUSED_BASE_COLOR_FACTOR}, | |
| 343 | + {Material::Property::EMISSIVE_FACTOR, FOCUSED_EMISSIVE_FACTOR}, | |
| 344 | + {Material::Property::METALLIC_FACTOR, FOCUSED_METALLIC_FACTOR}, | |
| 345 | + {Material::Property::ROUGHNESS_FACTOR, FOCUSED_ROUGHNESS_FACTOR}, | |
| 346 | + }); | |
| 347 | + } | |
| 348 | + } | |
| 349 | + | |
| 350 | + void OnFocusLost(Control control) | |
| 351 | + { | |
| 352 | + std::ostringstream oss; | |
| 353 | + oss << "Focus lost : ["; | |
| 354 | + oss << (control ? control.GetProperty<std::string>(Actor::Property::NAME) : "(nil)"); | |
| 355 | + oss << "]"; | |
| 356 | + ApplyBackLog(oss.str()); | |
| 357 | + | |
| 358 | + Model model = Model::DownCast(control); | |
| 359 | + if(model) | |
| 360 | + { | |
| 361 | + bool isSubModel = model.GetProperty<std::string>(Actor::Property::NAME) == "SubModel"; | |
| 362 | + ApplyAllMaterialPropertyRecursively( | |
| 363 | + model.GetModelRoot(), | |
| 364 | + { | |
| 365 | + {Material::Property::BASE_COLOR_FACTOR, isSubModel ? ORIGINAL_SUB_BASE_COLOR_FACTOR : ORIGINAL_BASE_COLOR_FACTOR}, | |
| 366 | + {Material::Property::EMISSIVE_FACTOR, isSubModel ? ORIGINAL_SUB_EMISSIVE_FACTOR : ORIGINAL_EMISSIVE_FACTOR}, | |
| 367 | + {Material::Property::METALLIC_FACTOR, isSubModel ? ORIGINAL_SUB_METALLIC_FACTOR : ORIGINAL_METALLIC_FACTOR}, | |
| 368 | + {Material::Property::ROUGHNESS_FACTOR, isSubModel ? ORIGINAL_SUB_ROUGHNESS_FACTOR : ORIGINAL_ROUGHNESS_FACTOR}, | |
| 369 | + }); | |
| 370 | + } | |
| 371 | + } | |
| 372 | + | |
| 373 | + bool OnTick() | |
| 374 | + { | |
| 375 | + if(mShowScreenExtent) | |
| 376 | + { | |
| 377 | + RecalculateScreenExtent(); | |
| 378 | + } | |
| 379 | + return true; | |
| 380 | + } | |
| 381 | + | |
| 382 | +private: | |
| 383 | + void ApplyResolution() | |
| 384 | + { | |
| 385 | + if(mWindow && mSceneView) | |
| 386 | + { | |
| 387 | + Window::WindowSize windowSize = mWindow.GetSize(); | |
| 388 | + switch(mResolutionType) | |
| 389 | + { | |
| 390 | + case ResolutionType::DEFAULT: | |
| 391 | + default: | |
| 392 | + { | |
| 393 | + mResolutionRate = 0.0f; | |
| 394 | + break; | |
| 395 | + } | |
| 396 | + case ResolutionType::DOWNSCALED: | |
| 397 | + { | |
| 398 | + mResolutionRate = RESOLUTION_RATE_DOWNSCALED; | |
| 399 | + break; | |
| 400 | + } | |
| 401 | + case ResolutionType::UPSCALED: | |
| 402 | + { | |
| 403 | + mResolutionRate = RESOLUTION_RATE_UPSCALED; | |
| 404 | + break; | |
| 405 | + } | |
| 406 | + case ResolutionType::OVER_DOWNSCALED: | |
| 407 | + { | |
| 408 | + mResolutionRate = RESOLUTION_RATE_OVER_DOWNSCALED; | |
| 409 | + break; | |
| 410 | + } | |
| 411 | + case ResolutionType::OVER_UPSCALED: | |
| 412 | + { | |
| 413 | + mResolutionRate = RESOLUTION_RATE_OVER_UPSCALED; | |
| 414 | + break; | |
| 415 | + } | |
| 416 | + } | |
| 417 | + | |
| 418 | + if(Dali::EqualsZero(mResolutionRate)) | |
| 419 | + { | |
| 420 | + mSceneView.ResetResolution(); | |
| 421 | + } | |
| 422 | + else | |
| 423 | + { | |
| 424 | + mSceneView.SetResolution(static_cast<uint32_t>(windowSize.GetWidth() * mResolutionRate), static_cast<uint32_t>(windowSize.GetHeight() * mResolutionRate)); | |
| 425 | + } | |
| 426 | + } | |
| 427 | + } | |
| 428 | + | |
| 429 | + void ApplyDebugLog() | |
| 430 | + { | |
| 431 | + if(!mDebugLabel) | |
| 432 | + { | |
| 433 | + mDebugLabel = TextLabel::New(); | |
| 434 | + mDebugLabel[Actor::Property::PARENT_ORIGIN] = ParentOrigin::TOP_LEFT; | |
| 435 | + mDebugLabel[Actor::Property::ANCHOR_POINT] = AnchorPoint::TOP_LEFT; | |
| 436 | + mDebugLabel[TextLabel::Property::MULTI_LINE] = true; | |
| 437 | + mDebugLabel[Control::Property::BACKGROUND] = Vector4(1.0f, 1.0f, 1.0f, 0.2f); | |
| 438 | + } | |
| 439 | + | |
| 440 | + if(mShowDebugLabel) | |
| 441 | + { | |
| 442 | + if(mWindow && mDebugLabel && !mDebugLabel.GetParent()) | |
| 443 | + { | |
| 444 | + mWindow.GetOverlayLayer().Add(mDebugLabel); | |
| 445 | + } | |
| 446 | + std::ostringstream oss; | |
| 447 | + oss << "Key 1 : Toggle to show debug log\n"; | |
| 448 | + oss << "Key 2 : Toggle to use Framebuffer. Currently " << (mUseFrameBuffer ? "ON" : "OFF") << "\n"; | |
| 449 | + oss << "Key 3 : Toggle to use FramebufferMultiSampling. Currently " << (mUseFrameBufferMultiSample ? FRAMEBUFFER_MULTI_SAMPLING_LEVEL : 0) << "\n"; | |
| 450 | + oss << "Key 4 : Toggle to use SetResolution. Currently "; | |
| 451 | + oss << (mResolutionType == ResolutionType::DEFAULT ? "DEFAULT" : mResolutionType == ResolutionType::DOWNSCALED ? "DOWNSCALED" | |
| 452 | + : mResolutionType == ResolutionType::UPSCALED ? "UPSCALED" | |
| 453 | + : mResolutionType == ResolutionType::OVER_DOWNSCALED ? "OVER_DOWNSCALED" | |
| 454 | + : mResolutionType == ResolutionType::OVER_UPSCALED ? "OVER_UPSCALED" | |
| 455 | + : "ERROR") | |
| 456 | + << " (Scale rate : " << mResolutionRate << ")\n"; | |
| 457 | + oss << "Key 5 : Toggle to Rotate camera. Currently " << (mRotateCamera ? "ON" : "OFF") << "\n"; | |
| 458 | + oss << "Key 6 : Toggle to show Model ScreenExtent. Currently " << (mShowScreenExtent ? "ON" : "OFF") << "\n"; | |
| 459 | + | |
| 460 | + for(const auto& log : mBackLog) | |
| 461 | + { | |
| 462 | + oss << log; | |
| 463 | + if(log.length() == 0 || log.back() != '\n') | |
| 464 | + { | |
| 465 | + oss << "\n"; | |
| 466 | + } | |
| 467 | + } | |
| 468 | + | |
| 469 | + mDebugLabel[TextLabel::Property::TEXT] = oss.str(); | |
| 470 | + } | |
| 471 | + else | |
| 472 | + { | |
| 473 | + if(mDebugLabel) | |
| 474 | + { | |
| 475 | + mDebugLabel.Unparent(); | |
| 476 | + } | |
| 477 | + } | |
| 478 | + } | |
| 479 | + | |
| 480 | + void ApplyBackLog(std::string message) | |
| 481 | + { | |
| 482 | + if(mBackLog.size() == MAX_BACKLOG_COUNT) | |
| 483 | + { | |
| 484 | + mBackLog.clear(); | |
| 485 | + } | |
| 486 | + mBackLog.push_back(message); | |
| 487 | + | |
| 488 | + ApplyDebugLog(); | |
| 489 | + } | |
| 490 | + | |
| 491 | + void ApplyModelScreenExtent(Control aabb, Model model) | |
| 492 | + { | |
| 493 | + Rect<float> screenExtent = Dali::DevelActor::CalculateCurrentScreenExtents(model); | |
| 494 | + | |
| 495 | + aabb[Actor::Property::POSITION_X] = screenExtent.x; | |
| 496 | + aabb[Actor::Property::POSITION_Y] = screenExtent.y; | |
| 497 | + aabb[Actor::Property::SIZE_WIDTH] = screenExtent.width; | |
| 498 | + aabb[Actor::Property::SIZE_HEIGHT] = screenExtent.height; | |
| 499 | + } | |
| 500 | + | |
| 501 | +private: | |
| 502 | + void RecalculateScreenExtent() | |
| 503 | + { | |
| 504 | + if(mWindow && !mMainModelAABB) | |
| 505 | + { | |
| 506 | + mMainModelAABB = Control::New(); | |
| 507 | + mMainModelAABB.SetProperties({ | |
| 508 | + {Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT}, | |
| 509 | + {Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT}, | |
| 510 | + {Control::Property::BACKGROUND, Vector4(0.0f, 0.0f, 1.0f, 0.2f)}, | |
| 511 | + }); | |
| 512 | + mWindow.GetOverlayLayer().Add(mMainModelAABB); | |
| 513 | + } | |
| 514 | + if(mWindow && !mSubModelAABB) | |
| 515 | + { | |
| 516 | + mSubModelAABB = Control::New(); | |
| 517 | + mSubModelAABB.SetProperties({ | |
| 518 | + {Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT}, | |
| 519 | + {Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT}, | |
| 520 | + {Control::Property::BACKGROUND, Vector4(1.0f, 0.0f, 0.0f, 0.2f)}, | |
| 521 | + }); | |
| 522 | + mWindow.GetOverlayLayer().Add(mSubModelAABB); | |
| 523 | + } | |
| 524 | + | |
| 525 | + ApplyModelScreenExtent(mMainModelAABB, mMainModel); | |
| 526 | + ApplyModelScreenExtent(mSubModelAABB, mSubModel); | |
| 527 | + } | |
| 528 | + | |
| 529 | +private: | |
| 530 | + Application& mApplication; | |
| 531 | + Window mWindow; | |
| 532 | + SceneView mSceneView; | |
| 533 | + | |
| 534 | + Model mMainModel; | |
| 535 | + Model mSubModel; | |
| 536 | + | |
| 537 | + Animation mCameraRotateAnimation; | |
| 538 | + | |
| 539 | + // State of demo | |
| 540 | + TextLabel mDebugLabel; | |
| 541 | + bool mShowDebugLabel{true}; | |
| 542 | + | |
| 543 | + std::vector<std::string> mBackLog; | |
| 544 | + | |
| 545 | + Timer mScreenExtentTimer; | |
| 546 | + Control mMainModelAABB; | |
| 547 | + Control mSubModelAABB; | |
| 548 | + | |
| 549 | + bool mUseFrameBuffer{false}; | |
| 550 | + bool mUseFrameBufferMultiSample{false}; | |
| 551 | + bool mRotateCamera{true}; | |
| 552 | + bool mShowScreenExtent{false}; | |
| 553 | + | |
| 554 | + ResolutionType mResolutionType{ResolutionType::DEFAULT}; | |
| 555 | + float mResolutionRate{0.0f}; | |
| 556 | +}; | |
| 557 | + | |
| 558 | +int DALI_EXPORT_API main(int argc, char** argv) | |
| 559 | +{ | |
| 560 | + Application application = Application::New(&argc, &argv); | |
| 561 | + SceneViewExample test(application); | |
| 562 | + application.MainLoop(); | |
| 563 | + return 0; | |
| 564 | +} | ... | ... |
examples/scene-view-test/scene-view-test.png
0 → 100755
995 KB
resources/po/en_GB.po
| ... | ... | @@ -223,6 +223,9 @@ msgstr "Renderer Stencil" |
| 223 | 223 | msgid "DALI_DEMO_STR_TITLE_SCENE_VIEW" |
| 224 | 224 | msgstr "Scene View" |
| 225 | 225 | |
| 226 | +msgid "DALI_DEMO_STR_TITLE_SCENE_VIEW_TEST" | |
| 227 | +msgstr "Scene View Test" | |
| 228 | + | |
| 226 | 229 | msgid "DALI_DEMO_STR_TITLE_SCENE3D" |
| 227 | 230 | msgstr "Scene3D" |
| 228 | 231 | ... | ... |
resources/po/en_US.po
| ... | ... | @@ -232,6 +232,9 @@ msgstr "Renderer Stencil" |
| 232 | 232 | msgid "DALI_DEMO_STR_TITLE_SCENE_VIEW" |
| 233 | 233 | msgstr "Scene View" |
| 234 | 234 | |
| 235 | +msgid "DALI_DEMO_STR_TITLE_SCENE_VIEW_TEST" | |
| 236 | +msgstr "Scene View Test" | |
| 237 | + | |
| 235 | 238 | msgid "DALI_DEMO_STR_TITLE_SCENE3D" |
| 236 | 239 | msgstr "Scene3D" |
| 237 | 240 | ... | ... |
shared/dali-demo-strings.h
| 1 | 1 | /* |
| 2 | - * Copyright (c) 2023 Samsung Electronics Co., Ltd. | |
| 2 | + * Copyright (c) 2024 Samsung Electronics Co., Ltd. | |
| 3 | 3 | * |
| 4 | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 | 5 | * you may not use this file except in compliance with the License. |
| ... | ... | @@ -123,6 +123,7 @@ extern "C" |
| 123 | 123 | #define DALI_DEMO_STR_TITLE_RENDERING_RAY_MARCHING dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_RENDERING_RAY_MARCHING") |
| 124 | 124 | #define DALI_DEMO_STR_TITLE_RENDERER_STENCIL dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_RENDERER_STENCIL") |
| 125 | 125 | #define DALI_DEMO_STR_TITLE_SCENE_VIEW dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_SCENE_VIEW") |
| 126 | +#define DALI_DEMO_STR_TITLE_SCENE_VIEW_TEST dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_SCENE_VIEW_TEST") | |
| 126 | 127 | #define DALI_DEMO_STR_TITLE_SCENE3D dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_SCENE3D") |
| 127 | 128 | #define DALI_DEMO_STR_TITLE_SCENE3D_LIGHT dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_SCENE3D_LIGHT") |
| 128 | 129 | #define DALI_DEMO_STR_TITLE_SCENE3D_MODEL dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_SCENE3D_MODEL") |
| ... | ... | @@ -246,6 +247,7 @@ extern "C" |
| 246 | 247 | #define DALI_DEMO_STR_TITLE_RENDERING_RADIAL_PROGRESS "Radial Progress" |
| 247 | 248 | #define DALI_DEMO_STR_TITLE_RENDERER_STENCIL "Renderer Stencils" |
| 248 | 249 | #define DALI_DEMO_STR_TITLE_SCENE_VIEW "Scene View" |
| 250 | +#define DALI_DEMO_STR_TITLE_SCENE_VIEW_TEST "Scene View Test" | |
| 249 | 251 | #define DALI_DEMO_STR_TITLE_SCENE3D "Scene3D" |
| 250 | 252 | #define DALI_DEMO_STR_TITLE_SCENE3D_LIGHT "Scene3D Light" |
| 251 | 253 | #define DALI_DEMO_STR_TITLE_SCENE3D_MODEL "Scene3D Model" | ... | ... |
tests-reel/dali-tests-reel.cpp
| 1 | 1 | /* |
| 2 | - * Copyright (c) 2023 Samsung Electronics Co., Ltd. | |
| 2 | + * Copyright (c) 2024 Samsung Electronics Co., Ltd. | |
| 3 | 3 | * |
| 4 | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 | 5 | * you may not use this file except in compliance with the License. |
| ... | ... | @@ -54,6 +54,7 @@ int DALI_EXPORT_API main(int argc, char** argv) |
| 54 | 54 | demo.AddExample(Example("text-overlap.example", DALI_DEMO_STR_TITLE_TEXT_OVERLAP)); |
| 55 | 55 | demo.AddExample(Example("visual-fitting-mode.example", DALI_DEMO_STR_TITLE_VISUAL_FITTING_MODE)); |
| 56 | 56 | demo.AddExample(Example("visual-transitions.example", DALI_DEMO_STR_TITLE_VISUAL_TRANSITIONS)); |
| 57 | + demo.AddExample(Example("scene-view-test.example", DALI_DEMO_STR_TITLE_SCENE_VIEW_TEST)); | |
| 57 | 58 | demo.AddExample(Example("simple-scroll-view.example", DALI_DEMO_STR_TITLE_SIMPLE_SCROLL_VIEW)); |
| 58 | 59 | demo.AddExample(Example("simple-text-label.example", DALI_DEMO_STR_TITLE_TEXT_LABEL)); |
| 59 | 60 | demo.AddExample(Example("simple-text-field.example", DALI_DEMO_STR_TITLE_TEXT_FIELD)); | ... | ... |