/* Copyright (C) 2010-2014 Kristian Duske This file is part of TrenchBroom. TrenchBroom is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. TrenchBroom is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with TrenchBroom. If not, see . */ #include "WalTextureLoader.h" #include "CollectionUtils.h" #include "Color.h" #include "ByteBuffer.h" #include "Exceptions.h" #include "StringUtils.h" #include "Assets/Palette.h" #include "Assets/Texture.h" #include "Assets/TextureCollection.h" #include "Assets/TextureCollectionSpec.h" #include "IO/DiskFileSystem.h" #include "IO/IOUtils.h" #include namespace TrenchBroom { namespace IO { WalTextureLoader::WalTextureLoader(const FileSystem& fs, const Assets::Palette& palette) : m_fs(fs), m_palette(palette) {} Assets::TextureCollection* WalTextureLoader::doLoadTextureCollection(const Assets::TextureCollectionSpec& spec) const { Path::List texturePaths = m_fs.findItems(spec.path(), FileSystem::ExtensionMatcher("wal")); std::sort(texturePaths.begin(), texturePaths.end()); Assets::TextureList textures; textures.reserve(texturePaths.size()); try { Path::List::const_iterator it, end; for (it = texturePaths.begin(), end = texturePaths.end(); it != end; ++it) { const Path& texturePath = *it; Assets::Texture* texture = readTexture(texturePath); textures.push_back(texture); } return new Assets::TextureCollection(spec.name(), textures); } catch (...) { VectorUtils::clearAndDelete(textures); throw; } } Assets::Texture* WalTextureLoader::readTexture(const IO::Path& path) const { MappedFile::Ptr file = m_fs.openFile(path); const char* cursor = file->begin(); advance(cursor); const size_t width = readSize(cursor); const size_t height = readSize(cursor); const String textureName = path.suffix(2).deleteExtension().asString('/'); Color tempColor, averageColor; Assets::TextureBuffer::List buffers(4); Assets::setMipBufferSize(buffers, width, height); const char* offsetCursor = file->begin() + 32 + 2*sizeof(uint32_t); for (size_t i = 0; i < 4; ++i) { const size_t divisor = 1 << i; const size_t offset = IO::readSize(offsetCursor); const char* mipCursor = file->begin() + offset; const size_t pixelCount = (width * height) / (divisor * divisor); m_palette.indexedToRgb(mipCursor, pixelCount, buffers[i], tempColor); if (i == 0) averageColor = tempColor; } return new Assets::Texture(textureName, width, height, averageColor, buffers); } } }