#pragma once #ifndef MESHTEXTURIZER_H #define MESHTEXTURIZER_H #include // TnzCore includes #include "traster.h" #include "tgl.h" // OpenGL includes // STL includes #include #include #undef DVAPI #undef DVVAR #ifdef TNZEXT_EXPORTS #define DVAPI DV_EXPORT_API #define DVVAR DV_EXPORT_VAR #else #define DVAPI DV_IMPORT_API #define DVVAR DV_IMPORT_VAR #endif //****************************************************************************************** // MeshTexturizer declaration //****************************************************************************************** /*! \brief The MeshTexturizer class acts as a management wrapper to OpenGL texturing capabilities, in particular concerning texture virtualization. \details The first step in OpenGL texturing requires copying a texture into the video ram (\a VRAM). Now, OpenGL documentation specifies that, although there is no limit to the \a number of allowed textures, there \a are limits to the \b size of said textures, which can be tested by asking OpenGL whether it can accommodate specific texture requests or not. Technically, the MeshTexturizer class acts as a virtualization manager that can be used to allow texturization with arbitrary texture sizes. The manager accepts raster images that are cut up into tiles and bound to VRAM. Please, observe that the number of texture objects is typically not an issue, as OpenGL is able to swap texture objects between RAM and VRAM, depending on which textures have been used most frequently. In other words, since MeshTexturizer ensures the granularity required by OpenGL, textures can be used until the process runs out of memory - of course, swapping can be a source of slowdowns, though. \remark Subdivision into tiles is designed to work for both premultiplied \a and non-premultiplied textures. \remark MeshTexturizer instances are thread-safe. */ class DVAPI MeshTexturizer { public: struct TextureData; enum PremultMode //! Premultiplication specifier for texture binding. { NONPREMULTIPLIED, //!< Texture is not premultiplied. PREMULTIPLIED, //!< Texture is premultiplied. }; public: MeshTexturizer(); ~MeshTexturizer(); /*! \details The bindTexture() function is used to specify a 32-bit fullcolor raster as a texture to be used for mesh rendering. The supplied geometry rect defines its position with respect to compiled meshes. \remark The premultiplication specifier is used to tell the texturizer how to add a proper transparent border surrounding texture tiles. This border is essential to draw transparent pixels beyond a texture tile's content. \returns The internal id used to reference to the input raster. */ int bindTexture( const TRaster32P &ras, const TRectD &geometry, //!< Moves a \a copy of the supplied raster image to VRAM, PremultMode premultiplyMode = NONPREMULTIPLIED); //! and assigns an identification number to it. //! \param ras Texture to be copied to VRAM. //! \param geometry The texture's geometry in //! the world - with respect to compiled meshes. //! \param premultiplyMode Specified whether ras //! is to be intended premultiplied or not. /*! \warning The pointer returned by getTextureData() is owned by this class - it must not be deleted. */ TextureData *getTextureData( int textureId); //!< Retrieves the texture data built from a previously //! bound texture image. \param //! textureId Identifier of the texture to be retrieved \returns See //! summary. /*! \details The texture identifier specified to rebindTexture() is retained, and the effect is that of an unbindTexture() - bindTexture() combo. \note Pre-compiled mesh data against the old texture can be retained \b if the newly supplied texture size and geometry are the \b same as the old one. */ void rebindTexture( int textureId, const TRaster32P &ras, const TRectD &geometry, //!< Rebinds the image bound to the specified texture PremultMode premultiplyMode = NONPREMULTIPLIED); //! id to a new image. void unbindTexture(int textureId); //!< Deletes the texture associated to the //! passed id. \param textureId //! Identifier of the texture to be //! unbound. private: class Imp; std::unique_ptr m_imp; private: // Not copyable MeshTexturizer(const MeshTexturizer &); MeshTexturizer &operator=(const MeshTexturizer &); }; //****************************************************************************************** // MeshTexturizer:::CompiledData definition //****************************************************************************************** /*! \brief The MeshTexturizer-owned data about a texture. \details The purpose of MeshTexturizer is that of storing in VRAM a set of textures cut up into tiles. This structure holds the data about the end-product of texture loading into a MeshTexturizer instance. */ struct MeshTexturizer::TextureData { struct TileData //! Data structure for a texture tile. { GLuint m_textureId; //!< OpenGL texture identifier. TRectD m_tileGeometry; //!< The tile's world geometry. }; public: TRectD m_geom; //!< The original texture's world geometry. std::vector m_tileDatas; //!< The texture tiles the original texture was split into. public: TextureData() {} TextureData(const TRectD &geom) : m_geom(geom) {} ~TextureData() { int t, tilesCount = m_tileDatas.size(); for (t = 0; t < tilesCount; ++t) glDeleteTextures(1, &m_tileDatas[t].m_textureId); } private: // Not copyable TextureData(const TextureData &); TextureData &operator=(const TextureData &); }; #endif // MESHTEXTURIZER_H