2 * Copyright (c) 2020 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 #include "ktx-loader.h"
22 #include <dali/devel-api/adaptor-framework/file-stream.h>
23 #include <dali/integration-api/debug.h>
34 uint32_t glType; //(UNSIGNED_BYTE, UNSIGNED_SHORT_5_6_5, etc.)
36 uint32_t glFormat; //(RGB, RGBA, BGRA, etc.)
37 uint32_t glInternalFormat; //For uncompressed textures, specifies the internalformat parameter passed to glTexStorage*D or glTexImage*D
38 uint32_t glBaseInternalFormat;
42 uint32_t numberOfArrayElements;
43 uint32_t numberOfFaces; //Cube map faces are stored in the order: +X, -X, +Y, -Y, +Z, -Z.
44 uint32_t numberOfMipmapLevels;
45 uint32_t bytesOfKeyValueData;
49 * Convert KTX format to Dali::Pixel::Format
51 bool ConvertPixelFormat(const uint32_t ktxPixelFormat, Dali::Pixel::Format& format)
53 switch(ktxPixelFormat)
55 case 0x93B0: // GL_COMPRESSED_RGBA_ASTC_4x4_KHR
57 format = Dali::Pixel::COMPRESSED_RGBA_ASTC_4x4_KHR;
60 case 0x881B: // GL_RGB16F
62 format = Dali::Pixel::RGB16F;
65 case 0x8815: // GL_RGB32F
67 format = Dali::Pixel::RGB32F;
70 case 0x8C3A: // GL_R11F_G11F_B10F
72 format = Dali::Pixel::RGB32F;
75 case 0x8D7C: // GL_RGBA8UI
77 format = Dali::Pixel::RGBA8888;
80 case 0x8D7D: // GL_RGB8UI
82 format = Dali::Pixel::RGB888;
94 bool LoadCubeMapFromKtxFile(const std::string& path, CubeData& cubedata)
96 std::unique_ptr<FILE, void (*)(FILE*)> fp(fopen(path.c_str(), "rb"), [](FILE* fp) {
107 KtxFileHeader header;
108 int result = fread(&header, sizeof(KtxFileHeader), 1u, fp.get());
114 // Skip the key-values:
115 if(fseek(fp.get(), header.bytesOfKeyValueData, SEEK_CUR))
120 cubedata.img.resize(header.numberOfFaces);
122 for(unsigned int face = 0; face < header.numberOfFaces; ++face) //array_element must be 0 or 1
124 cubedata.img[face].resize(header.numberOfMipmapLevels);
127 if(0 == header.numberOfMipmapLevels)
129 header.numberOfMipmapLevels = 1u;
132 if(0 == header.numberOfArrayElements)
134 header.numberOfArrayElements = 1u;
137 if(0 == header.pixelDepth)
139 header.pixelDepth = 1u;
142 if(0 == header.pixelHeight)
144 header.pixelHeight = 1u;
147 Dali::Pixel::Format daliformat = Pixel::RGB888;
149 ConvertPixelFormat(header.glInternalFormat, daliformat);
151 for(unsigned int mipmapLevel = 0; mipmapLevel < header.numberOfMipmapLevels; ++mipmapLevel)
153 uint32_t byteSize = 0;
154 if(fread(&byteSize, sizeof(byteSize), 1u, fp.get()) != 1)
159 if(0 != byteSize % 4u)
161 byteSize += 4u - byteSize % 4u;
164 for(unsigned int arrayElement = 0; arrayElement < header.numberOfArrayElements; ++arrayElement) // arrayElement must be 0 or 1
166 for(unsigned int face = 0; face < header.numberOfFaces; ++face)
168 std::unique_ptr<uint8_t, void (*)(void*)> img(static_cast<unsigned char*>(malloc(byteSize)), free); // resources will be freed when the PixelData is destroyed.
169 if(fread(img.get(), byteSize, 1u, fp.get()) != 1)
173 cubedata.img[face][mipmapLevel] = PixelData::New(img.release(), byteSize, header.pixelWidth, header.pixelHeight, daliformat, PixelData::FREE);
177 header.pixelHeight /= 2u;
178 header.pixelWidth /= 2u;
184 } // namespace PbrDemo