// This file is part of Noggit3, licensed under GNU General Public License (version 3). #pragma once #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include struct texture_heightmapping_data { texture_heightmapping_data(uint32_t scale = 0, float heightscale = 0, float heightoffset = 1.0f) { uvScale = scale; heightScale = heightscale; heightOffset = heightoffset; } uint32_t uvScale = 0; float heightScale = 0.0f; float heightOffset = 1.0f; }; struct tuple_hash { template std::size_t operator() (const std::tuple &p) const { auto h1 = std::hash{}(std::get<0>(p)); auto h2 = std::hash{}(std::get<1>(p)); auto h3 = std::hash{}(std::get<2>(p)); auto h4 = std::hash{}(std::get<3>(p)); return h1 ^ h2 ^ h3 ^ h4; // use hash combine here } }; struct BLPHeader; struct scoped_blp_texture_reference; struct blp_texture : public AsyncObject { blp_texture (BlizzardArchive::Listfile::FileKey const& filename, Noggit::NoggitRenderContext context); void finishLoading() override; virtual void waitForChildrenLoaded() override {}; void loadFromUncompressedData(BLPHeader const* lHeader, char const* lData); void loadFromCompressedData(BLPHeader const* lHeader, char const* lData); int width() const { return _width; } int height() const { return _height; } void bind(); void upload(); void uploadToArray(unsigned layer); void unload(); bool is_uploaded() { return _uploaded; }; GLuint texture_array() { return _texture_array; }; int array_index() { return _array_index; }; bool is_specular() { return _is_specular; }; unsigned mip_level() { return static_cast(!_compression_format ? _data.size() : _compressed_data.size()); }; std::map>& data() { return _data;}; std::map>& compressed_data() { return _compressed_data; }; std::optional const& compression_format() { return _compression_format; }; Noggit::NoggitRenderContext getContext() { return _context; }; [[nodiscard]] async_priority loading_priority() const override { return async_priority::high; } // Mists HeightMapping bool hasHeightMap() {return _has_heightmap; }; blp_texture* getHeightMap() { return heightMap.get(); }; private: bool _uploaded = false; int _width; int _height; Noggit::NoggitRenderContext _context; bool _is_specular = false; bool _is_tileset = false; bool _has_heightmap = false; private: std::map> _data; std::map> _compressed_data; std::optional _compression_format; int _array_index = -1; GLuint _texture_array = 0; std::unique_ptr heightMap; }; struct TexArrayParams { std::vector arrays; int n_used = 0; }; class TextureManager { public: static void report(); static void unload_all(Noggit::NoggitRenderContext context); static TexArrayParams& get_tex_array(int width, int height, int mip_level, Noggit::NoggitRenderContext context); static TexArrayParams& get_tex_array(GLint compression, int width, int height, int mip_level, std::map>& comp_data, Noggit::NoggitRenderContext context); private: friend struct scoped_blp_texture_reference; static Noggit::AsyncObjectMultimap _; static std::array, TexArrayParams, tuple_hash>, Noggit::NoggitRenderContext::count> _tex_arrays; }; struct scoped_blp_texture_reference { scoped_blp_texture_reference() = delete; scoped_blp_texture_reference (std::string const& filename, Noggit::NoggitRenderContext context); scoped_blp_texture_reference (scoped_blp_texture_reference const& other); scoped_blp_texture_reference (scoped_blp_texture_reference&&) = default; scoped_blp_texture_reference& operator= (scoped_blp_texture_reference const&) = delete; scoped_blp_texture_reference& operator= (scoped_blp_texture_reference&&) = default; ~scoped_blp_texture_reference() = default; blp_texture* operator->() const; blp_texture* get() const; bool operator== (scoped_blp_texture_reference const& other) const; bool use_cubemap = false; private: struct Deleter { void operator() (blp_texture*) const; }; std::unique_ptr _blp_texture; Noggit::NoggitRenderContext _context; }; namespace Noggit { class BLPRenderer { private: BLPRenderer() = default; BLPRenderer( const BLPRenderer&) = delete; BLPRenderer& operator=( BLPRenderer& ) = delete; std::map, QPixmap> _cache; std::unique_ptr _context; std::unique_ptr _fmt; std::unique_ptr _surface; std::unique_ptr _program; OpenGL::Scoped::deferred_upload_vertex_arrays<1> _vao; OpenGL::Scoped::deferred_upload_buffers<3> _buffers; bool _uploaded = false; public: static BLPRenderer& getInstance() { static BLPRenderer instance; return instance; } QPixmap* render_blp_to_pixmap ( std::string const& blp_filename, int width = -1, int height = -1); void unload(); void upload(); }; }