1 /* 2 Copyright (C) 2010-2014 Kristian Duske 3 4 This file is part of TrenchBroom. 5 6 TrenchBroom is free software: you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation, either version 3 of the License, or 9 (at your option) any later version. 10 11 TrenchBroom is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with TrenchBroom. If not, see <http://www.gnu.org/licenses/>. 18 */ 19 20 #include "WalTextureLoader.h" 21 22 #include "CollectionUtils.h" 23 #include "Color.h" 24 #include "ByteBuffer.h" 25 #include "Exceptions.h" 26 #include "StringUtils.h" 27 #include "Assets/Palette.h" 28 #include "Assets/Texture.h" 29 #include "Assets/TextureCollection.h" 30 #include "Assets/TextureCollectionSpec.h" 31 #include "IO/DiskFileSystem.h" 32 #include "IO/IOUtils.h" 33 34 #include <algorithm> 35 36 namespace TrenchBroom { 37 namespace IO { WalTextureLoader(const FileSystem & fs,const Assets::Palette & palette)38 WalTextureLoader::WalTextureLoader(const FileSystem& fs, const Assets::Palette& palette) : 39 m_fs(fs), 40 m_palette(palette) {} 41 doLoadTextureCollection(const Assets::TextureCollectionSpec & spec) const42 Assets::TextureCollection* WalTextureLoader::doLoadTextureCollection(const Assets::TextureCollectionSpec& spec) const { 43 Path::List texturePaths = m_fs.findItems(spec.path(), FileSystem::ExtensionMatcher("wal")); 44 std::sort(texturePaths.begin(), texturePaths.end()); 45 46 Assets::TextureList textures; 47 textures.reserve(texturePaths.size()); 48 49 try { 50 Path::List::const_iterator it, end; 51 for (it = texturePaths.begin(), end = texturePaths.end(); it != end; ++it) { 52 const Path& texturePath = *it; 53 Assets::Texture* texture = readTexture(texturePath); 54 textures.push_back(texture); 55 } 56 57 return new Assets::TextureCollection(spec.name(), textures); 58 } catch (...) { 59 VectorUtils::clearAndDelete(textures); 60 throw; 61 } 62 } 63 readTexture(const IO::Path & path) const64 Assets::Texture* WalTextureLoader::readTexture(const IO::Path& path) const { 65 MappedFile::Ptr file = m_fs.openFile(path); 66 const char* cursor = file->begin(); 67 68 advance<char[32]>(cursor); 69 const size_t width = readSize<uint32_t>(cursor); 70 const size_t height = readSize<uint32_t>(cursor); 71 const String textureName = path.suffix(2).deleteExtension().asString('/'); 72 73 Color tempColor, averageColor; 74 Assets::TextureBuffer::List buffers(4); 75 Assets::setMipBufferSize(buffers, width, height); 76 77 const char* offsetCursor = file->begin() + 32 + 2*sizeof(uint32_t); 78 for (size_t i = 0; i < 4; ++i) { 79 const size_t divisor = 1 << i; 80 const size_t offset = IO::readSize<int32_t>(offsetCursor); 81 const char* mipCursor = file->begin() + offset; 82 const size_t pixelCount = (width * height) / (divisor * divisor); 83 84 m_palette.indexedToRgb(mipCursor, pixelCount, buffers[i], tempColor); 85 if (i == 0) 86 averageColor = tempColor; 87 } 88 89 return new Assets::Texture(textureName, width, height, averageColor, buffers); 90 } 91 } 92 } 93