2 * Copyright (c) 2017 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"
33 uint32_t glType; //(UNSIGNED_BYTE, UNSIGNED_SHORT_5_6_5, etc.)
35 uint32_t glFormat; //(RGB, RGBA, BGRA, etc.)
36 uint32_t glInternalFormat; //For uncompressed textures, specifies the internalformat parameter passed to glTexStorage*D or glTexImage*D
37 uint32_t glBaseInternalFormat;
41 uint32_t numberOfArrayElements;
42 uint32_t numberOfFaces; //Cube map faces are stored in the order: +X, -X, +Y, -Y, +Z, -Z.
43 uint32_t numberOfMipmapLevels;
44 uint32_t bytesOfKeyValueData;
48 * Convert KTX format to Dali::Pixel::Format
50 bool ConvertPixelFormat(const uint32_t ktxPixelFormat, Dali::Pixel::Format& format)
52 switch( ktxPixelFormat )
54 case 0x93B0: // GL_COMPRESSED_RGBA_ASTC_4x4_KHR
56 format = Dali::Pixel::COMPRESSED_RGBA_ASTC_4x4_KHR;
59 case 0x881B:// GL_RGB16F
61 format = Dali::Pixel::RGB16F;
64 case 0x8815: // GL_RGB32F
66 format = Dali::Pixel::RGB32F;
69 case 0x8C3A: // GL_R11F_G11F_B10F
71 format = Dali::Pixel::RGB32F;
74 case 0x8D7C: // GL_RGBA8UI
76 format = Dali::Pixel::RGBA8888;
79 case 0x8D7D: // GL_RGB8UI
81 format = Dali::Pixel::RGB888;
93 bool LoadCubeMapFromKtxFile( const std::string& path, CubeData& cubedata )
95 FILE* fp = fopen(path.c_str(),"rb");
102 KtxFileHeader header;
104 int result = fread(&header,1,sizeof(KtxFileHeader),fp);
113 // Skip the key-values:
114 const long int imageSizeOffset = sizeof(KtxFileHeader) + header.bytesOfKeyValueData;
116 if( fseek(fp, imageSizeOffset, SEEK_END) )
131 if( fseek(fp, imageSizeOffset, SEEK_SET) )
137 cubedata.img.resize(header.numberOfFaces);
139 for(unsigned int face=0; face < header.numberOfFaces; ++face) //array_element must be 0 or 1
141 cubedata.img[face].resize(header.numberOfMipmapLevels);
144 unsigned char* buffer= reinterpret_cast<unsigned char*>( malloc( lSize ) );
146 unsigned char* img[6];
147 unsigned int imgSize[6];
148 unsigned char* imgPointer = buffer;
149 result = fread(buffer,1,lSize,fp);
159 if( 0 == header.numberOfMipmapLevels )
161 header.numberOfMipmapLevels = 1u;
164 if( 0 == header.numberOfArrayElements )
166 header.numberOfArrayElements = 1u;
169 if( 0 == header.pixelDepth )
171 header.pixelDepth = 1u;
174 if( 0 == header.pixelHeight )
176 header.pixelHeight = 1u;
179 Dali::Pixel::Format daliformat = Pixel::RGB888;
181 ConvertPixelFormat(header.glInternalFormat, daliformat);
183 for( unsigned int mipmapLevel = 0; mipmapLevel < header.numberOfMipmapLevels; ++mipmapLevel )
185 long int byteSize = 0;
187 memcpy(&imageSize,imgPointer,sizeof(unsigned int));
189 for(unsigned int arrayElement=0; arrayElement < header.numberOfArrayElements; ++arrayElement) //arrayElement must be 0 or 1
191 for(unsigned int face=0; face < header.numberOfFaces; ++face)
193 byteSize = imageSize;
196 byteSize += 4u - byteSize % 4u;
198 img[face] = reinterpret_cast<unsigned char*>( malloc( byteSize ) ); // resources will be freed when the PixelData is destroyed.
199 memcpy(img[face],imgPointer,byteSize);
200 imgSize[face] = byteSize;
201 imgPointer += byteSize;
202 cubedata.img[face][mipmapLevel] = PixelData::New( img[face], imgSize[face], header.pixelWidth , header.pixelHeight , daliformat, PixelData::FREE );
205 header.pixelHeight/=2u;
206 header.pixelWidth/=2u;
213 } // namespace PbrDemo