Merge "Supports cube map images in scene-loader" into devel/master
authorSeungho BAEK <sbsh.baek@samsung.com>
Mon, 18 Jul 2022 09:12:11 +0000 (09:12 +0000)
committerGerrit Code Review <gerrit@review>
Mon, 18 Jul 2022 09:12:11 +0000 (09:12 +0000)
19 files changed:
automated-tests/resources/cubemap_array_horizontal.png [new file with mode: 0644]
automated-tests/resources/cubemap_array_vertical.png [new file with mode: 0644]
automated-tests/resources/forest_diffuse_cubemap_cross_vertical.png [new file with mode: 0644]
automated-tests/src/dali-scene-loader/CMakeLists.txt
automated-tests/src/dali-scene-loader/utc-Dali-CubeLoader.cpp [new file with mode: 0644]
automated-tests/src/dali-scene-loader/utc-Dali-CubeMapLoader.cpp [new file with mode: 0644]
automated-tests/src/dali-scene-loader/utc-Dali-KtxLoader.cpp
dali-scene-loader/internal/controls/model-view/model-view-impl.cpp
dali-scene-loader/public-api/cube-data.cpp [new file with mode: 0644]
dali-scene-loader/public-api/cube-data.h [new file with mode: 0644]
dali-scene-loader/public-api/cube-loader.cpp [new file with mode: 0644]
dali-scene-loader/public-api/cube-loader.h [new file with mode: 0644]
dali-scene-loader/public-api/cube-map-loader.cpp [new file with mode: 0644]
dali-scene-loader/public-api/cube-map-loader.h [new file with mode: 0644]
dali-scene-loader/public-api/environment-definition.cpp
dali-scene-loader/public-api/environment-definition.h
dali-scene-loader/public-api/file.list
dali-scene-loader/public-api/ktx-loader.cpp
dali-scene-loader/public-api/ktx-loader.h

diff --git a/automated-tests/resources/cubemap_array_horizontal.png b/automated-tests/resources/cubemap_array_horizontal.png
new file mode 100644 (file)
index 0000000..a935915
Binary files /dev/null and b/automated-tests/resources/cubemap_array_horizontal.png differ
diff --git a/automated-tests/resources/cubemap_array_vertical.png b/automated-tests/resources/cubemap_array_vertical.png
new file mode 100644 (file)
index 0000000..d6bf296
Binary files /dev/null and b/automated-tests/resources/cubemap_array_vertical.png differ
diff --git a/automated-tests/resources/forest_diffuse_cubemap_cross_vertical.png b/automated-tests/resources/forest_diffuse_cubemap_cross_vertical.png
new file mode 100644 (file)
index 0000000..6e6bf0f
Binary files /dev/null and b/automated-tests/resources/forest_diffuse_cubemap_cross_vertical.png differ
index 387fb7b..1862dfe 100755 (executable)
@@ -11,6 +11,8 @@ SET(TC_SOURCES
   utc-Dali-AnimationDefinition.cpp
   utc-Dali-AnimatedProperty.cpp
   utc-Dali-CameraParameters.cpp
+  utc-Dali-CubeLoader.cpp
+  utc-Dali-CubeMapLoader.cpp
   utc-Dali-DliLoader.cpp
   utc-Dali-EnvironmentDefinition.cpp
   utc-Dali-FacialAnimation.cpp
diff --git a/automated-tests/src/dali-scene-loader/utc-Dali-CubeLoader.cpp b/automated-tests/src/dali-scene-loader/utc-Dali-CubeLoader.cpp
new file mode 100644 (file)
index 0000000..e48f0cd
--- /dev/null
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// Enable debug log for test coverage
+#define DEBUG_ENABLED 1
+
+#include "dali-scene-loader/public-api/cube-loader.h"
+#include <dali-test-suite-utils.h>
+#include <string_view>
+
+#include <fstream>
+
+using namespace Dali;
+using namespace Dali::SceneLoader;
+
+int UtcDaliCubeLoaderFailNonexistent(void)
+{
+  CubeData data;
+  DALI_TEST_CHECK(!LoadCubeData("non-existent.jpg", data));
+  END_TEST;
+}
+
+int UtcDaliCubeLoaderFailInvalid1(void)
+{
+  CubeData data;
+  DALI_TEST_CHECK(!LoadCubeData(TEST_RESOURCE_DIR "/gallery-small-1.jpg", data)); // Wrong sized image
+  END_TEST;
+}
+
+int UtcDaliCubeLoaderSuccess01(void)
+{
+  CubeData cubeData;
+  auto path = TEST_RESOURCE_DIR "/forest_diffuse_cubemap.png";  // cross horizontal
+  DALI_TEST_CHECK(LoadCubeData(path, cubeData));
+
+  DALI_TEST_EQUAL(6u, cubeData.data.size());
+  for (auto& face: cubeData.data)
+  {
+    uint32_t size = 512;
+    DALI_TEST_EQUAL(size, face[0].GetWidth());
+    DALI_TEST_EQUAL(size, face[0].GetHeight());
+    DALI_TEST_EQUAL(Pixel::Format::RGBA8888, face[0].GetPixelFormat());
+  }
+
+  END_TEST;
+}
+
+int UtcDaliCubeLoaderSuccess02(void)
+{
+  CubeData cubeData;
+  auto path = TEST_RESOURCE_DIR "/forest_diffuse_cubemap_cross_vertical.png"; // cross vertical
+  DALI_TEST_CHECK(LoadCubeData(path, cubeData));
+
+  DALI_TEST_EQUAL(6u, cubeData.data.size());
+  for (auto& face: cubeData.data)
+  {
+    uint32_t size = 256;
+    DALI_TEST_EQUAL(size, face[0].GetWidth());
+    DALI_TEST_EQUAL(size, face[0].GetHeight());
+    DALI_TEST_EQUAL(Pixel::Format::RGBA8888, face[0].GetPixelFormat());
+  }
+
+  END_TEST;
+}
+
+int UtcDaliCubeLoaderSuccess03(void)
+{
+  CubeData cubeData;
+  auto path = TEST_RESOURCE_DIR "/cubemap_array_horizontal.png"; // array horizontal
+  DALI_TEST_CHECK(LoadCubeData(path, cubeData));
+
+  DALI_TEST_EQUAL(6u, cubeData.data.size());
+  for (auto& face: cubeData.data)
+  {
+    uint32_t size = 100;
+    DALI_TEST_EQUAL(size, face[0].GetWidth());
+    DALI_TEST_EQUAL(size, face[0].GetHeight());
+    DALI_TEST_EQUAL(Pixel::Format::RGB888, face[0].GetPixelFormat());
+  }
+
+  END_TEST;
+}
+
+int UtcDaliCubeLoaderSuccess04(void)
+{
+  CubeData cubeData;
+  auto path = TEST_RESOURCE_DIR "/cubemap_array_vertical.png"; // array horizontal
+  DALI_TEST_CHECK(LoadCubeData(path, cubeData));
+
+  DALI_TEST_EQUAL(6u, cubeData.data.size());
+  for (auto& face: cubeData.data)
+  {
+    uint32_t size = 100;
+    DALI_TEST_EQUAL(size, face[0].GetWidth());
+    DALI_TEST_EQUAL(size, face[0].GetHeight());
+    DALI_TEST_EQUAL(Pixel::Format::RGB888, face[0].GetPixelFormat());
+  }
+
+  END_TEST;
+}
+
+int UtcDaliCubeLoaderCubeDataCreateTexture(void)
+{
+  CubeData cubeData;
+  auto path = TEST_RESOURCE_DIR "/forest_diffuse_cubemap.png";
+  DALI_TEST_CHECK(LoadCubeData(path, cubeData));
+
+  TestApplication app;
+  auto texture = cubeData.CreateTexture();
+
+  DALI_TEST_CHECK(texture);
+  DALI_TEST_EQUAL(512u, texture.GetWidth());
+  DALI_TEST_EQUAL(512u, texture.GetHeight());
+
+  END_TEST;
+}
diff --git a/automated-tests/src/dali-scene-loader/utc-Dali-CubeMapLoader.cpp b/automated-tests/src/dali-scene-loader/utc-Dali-CubeMapLoader.cpp
new file mode 100644 (file)
index 0000000..4c6f4f0
--- /dev/null
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// Enable debug log for test coverage
+#define DEBUG_ENABLED 1
+
+#include "dali-scene-loader/public-api/cube-map-loader.h"
+#include <dali-test-suite-utils.h>
+#include <string_view>
+
+#include <fstream>
+
+using namespace Dali;
+using namespace Dali::SceneLoader;
+
+int UtcDaliCubeMapLoaderFailNonexistent(void)
+{
+  CubeData data;
+  DALI_TEST_CHECK(!LoadCubeMapData("non-existent.jpg", data));
+  END_TEST;
+}
+
+int UtcDaliCubeMapLoaderFailInvalid1(void)
+{
+  CubeData data;
+  DALI_TEST_CHECK(!LoadCubeMapData(TEST_RESOURCE_DIR "/gallery-small-1.jpg", data)); // Wrong sized image
+  END_TEST;
+}
+
+int UtcDaliCubeMapLoaderSuccess01(void)
+{
+  CubeData cubeData;
+  auto path = TEST_RESOURCE_DIR "/forest_radiance.ktx";
+  DALI_TEST_CHECK(LoadCubeMapData(path, cubeData));
+
+  DALI_TEST_EQUAL(6u, cubeData.data.size());
+  for (auto& face: cubeData.data)
+  {
+    uint32_t size = 64;
+    for (auto& mipData: face)
+    {
+      DALI_TEST_EQUAL(size, mipData.GetWidth());
+      DALI_TEST_EQUAL(size, mipData.GetHeight());
+      DALI_TEST_EQUAL(Pixel::Format::RGB888, mipData.GetPixelFormat());
+      size /= 2;
+    }
+  }
+
+  END_TEST;
+}
+
+int UtcDaliCubeMapLoaderSuccess02(void)
+{
+  CubeData cubeData;
+  auto path = TEST_RESOURCE_DIR "/forest_diffuse_cubemap.png";  // cross horizontal
+  DALI_TEST_CHECK(LoadCubeMapData(path, cubeData));
+
+  DALI_TEST_EQUAL(6u, cubeData.data.size());
+  for (auto& face: cubeData.data)
+  {
+    uint32_t size = 512;
+    DALI_TEST_EQUAL(size, face[0].GetWidth());
+    DALI_TEST_EQUAL(size, face[0].GetHeight());
+    DALI_TEST_EQUAL(Pixel::Format::RGBA8888, face[0].GetPixelFormat());
+  }
+
+  END_TEST;
+}
+
+int UtcDaliCubeMapLoaderCubeDataCreateTexture01(void)
+{
+  CubeData cubeData;
+  auto path = TEST_RESOURCE_DIR "/forest_radiance.ktx";
+  DALI_TEST_CHECK(LoadCubeMapData(path, cubeData));
+
+  TestApplication app;
+  auto texture = cubeData.CreateTexture();
+
+  DALI_TEST_CHECK(texture);
+  DALI_TEST_EQUAL(64u, texture.GetWidth());
+  DALI_TEST_EQUAL(64u, texture.GetHeight());
+
+  END_TEST;
+}
+
+int UtcDaliCubeMapLoaderCubeDataCreateTexture02(void)
+{
+  CubeData cubeData;
+  auto path = TEST_RESOURCE_DIR "/forest_diffuse_cubemap.png";
+  DALI_TEST_CHECK(LoadCubeMapData(path, cubeData));
+
+  TestApplication app;
+  auto texture = cubeData.CreateTexture();
+
+  DALI_TEST_CHECK(texture);
+  DALI_TEST_EQUAL(512u, texture.GetWidth());
+  DALI_TEST_EQUAL(512u, texture.GetHeight());
+
+  END_TEST;
+}
index 783745d..f351b55 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -30,28 +30,28 @@ using namespace Dali::SceneLoader;
 int UtcDaliKtxLoaderFailNonexistent(void)
 {
   CubeData data;
-  DALI_TEST_CHECK(!LoadCubeMapData("non-existent.ktx", data));
+  DALI_TEST_CHECK(!LoadKtxData("non-existent.ktx", data));
   END_TEST;
 }
 
 int UtcDaliKtxLoaderFailInvalid1(void)
 {
   CubeData data;
-  DALI_TEST_CHECK(!LoadCubeMapData(TEST_RESOURCE_DIR "/invalid.svg", data)); // file smaller than KTX header
+  DALI_TEST_CHECK(!LoadKtxData(TEST_RESOURCE_DIR "/invalid.svg", data)); // file smaller than KTX header
   END_TEST;
 }
 
 int UtcDaliKtxLoaderFailInvalid2(void)
 {
   CubeData data;
-  DALI_TEST_CHECK(!LoadCubeMapData(TEST_RESOURCE_DIR "/anim.gif", data)); // not a KTX
+  DALI_TEST_CHECK(!LoadKtxData(TEST_RESOURCE_DIR "/anim.gif", data)); // not a KTX
   END_TEST;
 }
 
 int UtcDaliKtxLoaderFailTruncated(void)
 {
   CubeData data;
-  DALI_TEST_CHECK(!LoadCubeMapData(TEST_RESOURCE_DIR "/truncated.ktx", data));
+  DALI_TEST_CHECK(!LoadKtxData(TEST_RESOURCE_DIR "/truncated.ktx", data));
   END_TEST;
 }
 
@@ -59,7 +59,7 @@ int UtcDaliKtxLoaderSuccess(void)
 {
   CubeData cubeData;
   auto path = TEST_RESOURCE_DIR "/forest_radiance.ktx";
-  DALI_TEST_CHECK(LoadCubeMapData(path, cubeData));
+  DALI_TEST_CHECK(LoadKtxData(path, cubeData));
 
   DALI_TEST_EQUAL(6u, cubeData.data.size());
   for (auto& face: cubeData.data)
@@ -103,7 +103,7 @@ int UtcDaliKtxLoaderFormats(void)
   for (auto i : pathFormats)
   {
     CubeData cubeData;
-    DALI_TEST_CHECK(LoadCubeMapData(resPath + i.first + ".ktx", cubeData));
+    DALI_TEST_CHECK(LoadKtxData(resPath + i.first + ".ktx", cubeData));
     DALI_TEST_EQUAL(cubeData.data[0][0].GetPixelFormat(), i.second);
   }
 
@@ -135,7 +135,7 @@ int UtcDaliKtxLoaderCubeDataCreateTexture2(void)
 {
   CubeData cubeData;
   auto path = TEST_RESOURCE_DIR "/forest_radiance.ktx";
-  DALI_TEST_CHECK(LoadCubeMapData(path, cubeData));
+  DALI_TEST_CHECK(LoadKtxData(path, cubeData));
 
   TestApplication app;
   auto texture = cubeData.CreateTexture();
@@ -151,7 +151,7 @@ int UtcDaliKtxLoaderCubeDataCreateTexture3(void)
 {
   CubeData cubeData;
   auto path = TEST_RESOURCE_DIR "/papermill_E_diffuse-64.ktx";
-  DALI_TEST_CHECK(LoadCubeMapData(path, cubeData));
+  DALI_TEST_CHECK(LoadKtxData(path, cubeData));
 
   TestApplication app;
   auto texture = cubeData.CreateTexture();
index 0004aac..f3b135a 100644 (file)
@@ -19,8 +19,6 @@
 #include "model-view-impl.h"
 
 // EXTERNAL INCLUDES
-#include <dali/devel-api/adaptor-framework/image-loading.h>
-#include <dali/devel-api/adaptor-framework/pixel-buffer.h>
 #include <dali-toolkit/dali-toolkit.h>
 #include <dali-toolkit/devel-api/controls/control-devel.h>
 #include <dali-toolkit/internal/controls/control/control-data-impl.h>
@@ -41,6 +39,8 @@
 #include <dali-scene-loader/public-api/scene-definition.h>
 #include <dali-scene-loader/public-api/shader-definition-factory.h>
 #include <dali-scene-loader/public-api/controls/model-view/model-view.h>
+#include <dali-scene-loader/public-api/cube-map-loader.h>
+#include <dali-scene-loader/public-api/cube-data.h>
 
 using namespace Dali;
 
@@ -115,22 +115,15 @@ struct BoundingVolume
 
 Texture LoadCubeMap(const std::string& cubeMapPath)
 {
-  std::filesystem::path modelPath(cubeMapPath);
-  std::string           extension = modelPath.extension();
-  std::transform(extension.begin(), extension.end(), extension.begin(), ::tolower);
-
-  Texture cubeTexture;
-  if(extension == KTX_EXTENSION)
+  Texture               cubeTexture;
+  SceneLoader::CubeData cubeData;
+  if(SceneLoader::LoadCubeMapData(cubeMapPath, cubeData))
   {
-    SceneLoader::CubeData cubeData;
-    if(SceneLoader::LoadCubeMapData(cubeMapPath, cubeData))
-    {
-      cubeTexture = cubeData.CreateTexture();
-    }
-    else
-    {
-      DALI_LOG_ERROR("Fail to load cube map, %s\n", cubeMapPath.c_str());
-    }
+    cubeTexture = cubeData.CreateTexture();
+  }
+  else
+  {
+    DALI_LOG_ERROR("Fail to load cube map, %s\n", cubeMapPath.c_str());
   }
 
   return cubeTexture;
diff --git a/dali-scene-loader/public-api/cube-data.cpp b/dali-scene-loader/public-api/cube-data.cpp
new file mode 100644 (file)
index 0000000..b87507e
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// FILE HEADER
+#include "dali-scene-loader/public-api/cube-data.h"
+
+// EXTERNAL INCLUDES
+#include "dali/public-api/rendering/texture.h"
+
+namespace Dali
+{
+namespace SceneLoader
+{
+
+Texture CubeData::CreateTexture() const
+{
+  Texture texture = Texture::New(TextureType::TEXTURE_CUBE, data[0][0].GetPixelFormat(), data[0][0].GetWidth(), data[0][0].GetHeight());
+  for(size_t iSide = 0u, iEndSize = data.size(); iSide < iEndSize; ++iSide)
+  {
+    auto& side = data[iSide];
+    for(size_t iMipLevel = 0u, iEndMipLevel = data[0].size(); iMipLevel < iEndMipLevel; ++iMipLevel)
+    {
+      texture.Upload(side[iMipLevel], CubeMapLayer::POSITIVE_X + iSide, iMipLevel, 0u, 0u, side[iMipLevel].GetWidth(), side[iMipLevel].GetHeight());
+    }
+  }
+
+  // If mipmap is not defined explicitly, use GenerateMipmaps.
+  // TODO: Maybe we can use better way to know it already has mipmap or not.
+  if(data.size() > 0u && data[0].size() == 1u)
+  {
+    texture.GenerateMipmaps();
+  }
+
+  return texture;
+}
+
+} // namespace SceneLoader
+} // namespace Dali
diff --git a/dali-scene-loader/public-api/cube-data.h b/dali-scene-loader/public-api/cube-data.h
new file mode 100644 (file)
index 0000000..94c34de
--- /dev/null
@@ -0,0 +1,51 @@
+#ifndef DALI_SCENE_LOADER_CUBE_DATA_H
+#define DALI_SCENE_LOADER_CUBE_DATA_H
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include "dali-scene-loader/public-api/api.h"
+
+// EXTERNAL INCLUDES
+#include "dali/public-api/common/vector-wrapper.h"
+#include "dali/public-api/images/pixel-data.h"
+#include "dali/public-api/rendering/texture.h"
+
+namespace Dali
+{
+namespace SceneLoader
+{
+/**
+ * @brief Stores the pixel data objects for each face of the cube texture and their mipmaps.
+ */
+class DALI_SCENE_LOADER_API CubeData
+{
+public:
+  /**
+   * @brief Create cube texture from image file
+   * @return Texture loaded cube texture.
+   */
+  Texture CreateTexture() const;
+
+public:
+  std::vector<std::vector<PixelData> > data;
+};
+
+} // namespace SceneLoader
+} // namespace Dali
+
+#endif // DALI_SCENE_LOADER_CUBE_DATA_H
diff --git a/dali-scene-loader/public-api/cube-loader.cpp b/dali-scene-loader/public-api/cube-loader.cpp
new file mode 100644 (file)
index 0000000..4fbdbc9
--- /dev/null
@@ -0,0 +1,151 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// FILE HEADER
+#include <dali-scene-loader/public-api/cube-loader.h>
+
+// EXTERNAL INCLUDES
+#include <dali/devel-api/adaptor-framework/image-loading.h>
+#include <dali/devel-api/adaptor-framework/pixel-buffer.h>
+#include <dali/public-api/common/vector-wrapper.h>
+#include <dali/public-api/rendering/texture.h>
+#include <dali/integration-api/debug.h>
+#include <string.h>
+
+namespace Dali
+{
+namespace
+{
+/**
+ * @brief cube map face index
+ * Cube map layer order is as fallows:
+ * POSITIVE_X, NEGATIVE_X, POSITIVE_Y, NEGATIVE_Y, POSITIVE_Z, NEGATIVE_Z. @see CubeMapLayer
+ * The indices are for 4 kind of environment cube map. Cross_horizontal, Array_horizontal, Cross_vertical, and Array_vertical.
+ */
+const uint32_t CUBEMAP_INDEX_X[4][6] = {{2, 0, 1, 1, 1, 3}, {0, 1, 2, 3, 4, 5}, {1, 1, 1, 1, 0, 2}, {0, 0, 0, 0, 0, 0}};
+const uint32_t CUBEMAP_INDEX_Y[4][6] = {{1, 1, 0, 2, 1, 1}, {0, 0, 0, 0, 0, 0}, {1, 3, 0, 2, 1, 1}, {0, 1, 2, 3, 4, 5}};
+
+enum CubeType
+{
+  CROSS_HORIZONTAL = 0, // Cross horizontal style cube map
+  ARRAY_HORIZONTAL,     // array horizontal style cube map
+  CROSS_VERTICAL,       // Cross vertical style cube map
+  ARRAY_VERTICAL,       // array vertical style cube map
+  NONE
+};
+
+uint8_t* GetCroppedBuffer(uint8_t* sourceBuffer, uint32_t bytesPerPixel, uint32_t width, uint32_t height, uint32_t xOffset, uint32_t yOffset, uint32_t xFaceSize, uint32_t yFaceSize)
+{
+  uint32_t byteSize   = bytesPerPixel * xFaceSize * yFaceSize;
+  uint8_t* destBuffer = reinterpret_cast<uint8_t*>(malloc(byteSize + 4u));
+
+  int32_t srcStride  = width * bytesPerPixel;
+  int32_t destStride = xFaceSize * bytesPerPixel;
+  int32_t srcOffset  = xOffset * bytesPerPixel + yOffset * srcStride;
+  int32_t destOffset = 0;
+  for(uint16_t row = yOffset; row < yOffset + yFaceSize; ++row)
+  {
+    memcpy(destBuffer + destOffset, sourceBuffer + srcOffset, destStride);
+    srcOffset += srcStride;
+    destOffset += destStride;
+  }
+
+  return destBuffer;
+}
+
+PixelData GetCubeFace(Devel::PixelBuffer pixelBuffer, uint32_t faceIndex, CubeType cubeType, uint32_t faceSize)
+{
+  PixelData pixelData;
+  if(cubeType != NONE)
+  {
+    uint8_t* imageBuffer   = pixelBuffer.GetBuffer();
+    uint32_t bytesPerPixel = Pixel::GetBytesPerPixel(pixelBuffer.GetPixelFormat());
+    uint32_t imageWidth    = pixelBuffer.GetWidth();
+    uint32_t imageHeight   = pixelBuffer.GetHeight();
+
+    uint32_t xOffset = CUBEMAP_INDEX_X[cubeType][faceIndex] * faceSize;
+    uint32_t yOffset = CUBEMAP_INDEX_Y[cubeType][faceIndex] * faceSize;
+
+    uint8_t* tempImageBuffer = GetCroppedBuffer(imageBuffer, bytesPerPixel, imageWidth, imageHeight, xOffset, yOffset, faceSize, faceSize);
+    pixelData                = PixelData::New(tempImageBuffer, faceSize * faceSize * bytesPerPixel, faceSize, faceSize, pixelBuffer.GetPixelFormat(), PixelData::FREE);
+  }
+  return pixelData;
+}
+} // namespace
+
+namespace SceneLoader
+{
+bool LoadCubeData(const std::string& path, CubeData& cubedata)
+{
+  Texture cubeTexture;
+  // Diffuse Cube Map
+  if(path.empty())
+  {
+    return false;
+  }
+
+  Devel::PixelBuffer pixelBuffer = LoadImageFromFile(path);
+  if(pixelBuffer)
+  {
+    uint32_t imageWidth  = pixelBuffer.GetWidth();
+    uint32_t imageHeight = pixelBuffer.GetHeight();
+
+    uint32_t faceSize = 0;
+    CubeType cubeType = NONE;
+    if(imageWidth / 4 == imageHeight / 3)
+    {
+      cubeType = CROSS_HORIZONTAL;
+      faceSize = imageWidth / 4;
+    }
+    else if(imageWidth / 6 == imageHeight)
+    {
+      cubeType = ARRAY_HORIZONTAL;
+      faceSize = imageHeight;
+    }
+    else if(imageWidth / 3 == imageHeight / 4)
+    {
+      cubeType = CROSS_VERTICAL;
+      faceSize = imageHeight / 4;
+    }
+    else if(imageWidth == imageHeight / 6)
+    {
+      cubeType = ARRAY_VERTICAL;
+      faceSize = imageWidth;
+    }
+    else
+    {
+      DALI_LOG_ERROR("The image is not a cube map\n");
+      return false;
+    }
+
+    cubedata.data.resize(6);
+    for(uint32_t i = 0; i < 6; ++i)
+    {
+      cubedata.data[i].resize(1);
+    }
+    for(uint32_t i = 0; i < 6; ++i)
+    {
+      cubedata.data[i][0] = GetCubeFace(pixelBuffer, i, cubeType, faceSize);
+    }
+
+    return true;
+  }
+  return false;
+}
+
+} // namespace SceneLoader
+} // namespace Dali
diff --git a/dali-scene-loader/public-api/cube-loader.h b/dali-scene-loader/public-api/cube-loader.h
new file mode 100644 (file)
index 0000000..535d228
--- /dev/null
@@ -0,0 +1,41 @@
+#ifndef DALI_SCENE_LOADER_CUBE_LOADER_H
+#define DALI_SCENE_LOADER_CUBE_LOADER_H
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include <dali-scene-loader/public-api/api.h>
+#include <dali-scene-loader/public-api/cube-data.h>
+
+namespace Dali
+{
+namespace SceneLoader
+{
+
+/**
+ * @brief Loads cube map data texture from a cube style image file.
+ *
+ * @param[in] path The file path.
+ * @param[out] cubedata The data structure with all pixel data objects.
+ * @return bool True if the loading is succeded.
+ */
+bool LoadCubeData(const std::string& path, CubeData& cubedata);
+
+} // namespace SceneLoader
+} // namespace Dali
+
+#endif // DALI_SCENE_LOADER_CUBE_LOADER_H
diff --git a/dali-scene-loader/public-api/cube-map-loader.cpp b/dali-scene-loader/public-api/cube-map-loader.cpp
new file mode 100644 (file)
index 0000000..b11d297
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// FILE HEADER
+#include <dali-scene-loader/public-api/cube-map-loader.h>
+
+// INTERNAL INCLUDES
+#include <dali-scene-loader/public-api/ktx-loader.h>
+#include <dali-scene-loader/public-api/cube-loader.h>
+
+// EXTERNAL INCLUDES
+#include <filesystem>
+
+namespace Dali
+{
+namespace
+{
+
+const std::string_view KTX_EXTENSION = ".ktx";
+
+}
+
+namespace SceneLoader
+{
+
+bool LoadCubeMapData(const std::string& path, CubeData& cubedata)
+{
+  std::filesystem::path modelPath(path);
+  std::string           extension = modelPath.extension();
+  std::transform(extension.begin(), extension.end(), extension.begin(), ::tolower);
+
+  return (extension == KTX_EXTENSION) ? SceneLoader::LoadKtxData(path, cubedata) : SceneLoader::LoadCubeData(path, cubedata);
+}
+
+} // namespace SceneLoader
+} // namespace Dali
diff --git a/dali-scene-loader/public-api/cube-map-loader.h b/dali-scene-loader/public-api/cube-map-loader.h
new file mode 100644 (file)
index 0000000..7b85a98
--- /dev/null
@@ -0,0 +1,41 @@
+#ifndef DALI_SCENE_LOADER_CUBE_MAP_LOADER_H
+#define DALI_SCENE_LOADER_CUBE_MAP_LOADER_H
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include <dali-scene-loader/public-api/api.h>
+#include <dali-scene-loader/public-api/cube-data.h>
+
+namespace Dali
+{
+namespace SceneLoader
+{
+
+/**
+ * @brief Loads cube map data texture from a cube map file.
+ *
+ * @param[in] path The file path.
+ * @param[out] cubedata The data structure with all pixel data objects.
+ * @return bool True if the loading is succeded.
+ */
+bool LoadCubeMapData(const std::string& path, CubeData& cubedata);
+
+} // namespace SceneLoader
+} // namespace Dali
+
+#endif // DALI_SCENE_LOADER_CUBE_MAP_LOADER_H
index cc4e7e8..9b09b65 100644 (file)
@@ -22,6 +22,7 @@
 // INTERNAL INCLUDES
 #include "dali-scene-loader/public-api/environment-definition.h"
 #include "dali-scene-loader/public-api/utils.h"
+#include "dali-scene-loader/public-api/cube-map-loader.h"
 
 namespace
 {
index 0fcdee1..35d6ee9 100644 (file)
@@ -19,7 +19,7 @@
 
 // INTERNAL INCLUDES
 #include "dali-scene-loader/public-api/api.h"
-#include "dali-scene-loader/public-api/ktx-loader.h"
+#include "dali-scene-loader/public-api/cube-data.h"
 
 // EXTERNAL INCLUDES
 #include "dali/public-api/math/quaternion.h"
index dcdc4d3..92b1c91 100644 (file)
@@ -6,6 +6,9 @@ set(scene_loader_src_files ${scene_loader_src_files}
        ${scene_loader_public_api_dir}/animation-definition.cpp
        ${scene_loader_public_api_dir}/blend-shape-details.cpp
        ${scene_loader_public_api_dir}/camera-parameters.cpp
+       ${scene_loader_public_api_dir}/cube-data.cpp
+       ${scene_loader_public_api_dir}/cube-loader.cpp
+       ${scene_loader_public_api_dir}/cube-map-loader.cpp
        ${scene_loader_public_api_dir}/customization.cpp
        ${scene_loader_public_api_dir}/dli-loader.cpp
        ${scene_loader_public_api_dir}/environment-definition.cpp
index 857163d..a74c50c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  */
 
 // FILE HEADER
-#include "dali-scene-loader/public-api/ktx-loader.h"
+#include <dali-scene-loader/public-api/ktx-loader.h>
 
 // EXTERNAL INCLUDES
 #include <fstream>
 #include <memory>
-#include "dali/public-api/rendering/texture.h"
+#include <dali/public-api/rendering/texture.h>
 
 namespace Dali
 {
@@ -183,22 +183,7 @@ bool ConvertPixelFormat(const uint32_t ktxPixelFormat, Pixel::Format& format)
   return true;
 }
 
-Texture CubeData::CreateTexture() const
-{
-  Texture texture = Texture::New(TextureType::TEXTURE_CUBE, data[0][0].GetPixelFormat(), data[0][0].GetWidth(), data[0][0].GetHeight());
-  for(size_t iSide = 0u, iEndSize = data.size(); iSide < iEndSize; ++iSide)
-  {
-    auto& side = data[iSide];
-    for(size_t iMipLevel = 0u, iEndMipLevel = data[0].size(); iMipLevel < iEndMipLevel; ++iMipLevel)
-    {
-      texture.Upload(side[iMipLevel], CubeMapLayer::POSITIVE_X + iSide, iMipLevel, 0u, 0u, side[iMipLevel].GetWidth(), side[iMipLevel].GetHeight());
-    }
-  }
-
-  return texture;
-}
-
-bool LoadCubeMapData(const std::string& path, CubeData& cubedata)
+bool LoadKtxData(const std::string& path, CubeData& cubedata)
 {
   std::fstream fp(path, std::ios::in | std::ios::binary);
   if(fp.is_open() == false)
index d94f4ca..3a8b0e1 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef DALI_SCENE_LOADER_KTX_LOADER_H
 #define DALI_SCENE_LOADER_KTX_LOADER_H
 /*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  */
 
 // INTERNAL INCLUDES
-#include "dali-scene-loader/public-api/api.h"
-
-// EXTERNAL INCLUDES
-#include "dali/public-api/common/vector-wrapper.h"
-#include "dali/public-api/images/pixel-data.h"
-#include "dali/public-api/rendering/texture.h"
+#include <dali-scene-loader/public-api/api.h>
+#include <dali-scene-loader/public-api/cube-data.h>
 
 namespace Dali
 {
 namespace SceneLoader
 {
-/**
- * @brief Stores the pixel data objects for each face of the cube texture and their mipmaps.
- */
-struct DALI_SCENE_LOADER_API CubeData
-{
-  std::vector<std::vector<PixelData> > data;
-
-  Texture CreateTexture() const;
-};
 
 /**
  * @brief Loads cube map data texture from a ktx file.
  *
  * @param[in] path The file path.
  * @param[out] cubedata The data structure with all pixel data objects.
+ * @return bool True if the loading is succeded.
  */
-DALI_SCENE_LOADER_API bool LoadCubeMapData(const std::string& path, CubeData& cubedata);
+bool LoadKtxData(const std::string& path, CubeData& cubedata);
 
 } // namespace SceneLoader
 } // namespace Dali