GG
|
00001 // -*- C++ -*- 00002 /* GG is a GUI for SDL and OpenGL. 00003 Copyright (C) 2003-2008 T. Zachary Laine 00004 00005 This library is free software; you can redistribute it and/or 00006 modify it under the terms of the GNU Lesser General Public License 00007 as published by the Free Software Foundation; either version 2.1 00008 of the License, or (at your option) any later version. 00009 00010 This library is distributed in the hope that it will be useful, 00011 but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 Lesser General Public License for more details. 00014 00015 You should have received a copy of the GNU Lesser General Public 00016 License along with this library; if not, write to the Free 00017 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 00018 02111-1307 USA 00019 00020 If you do not wish to comply with the terms of the LGPL please 00021 contact the author as other terms are available for a fee. 00022 00023 Zach Laine 00024 whatwasthataddress@gmail.com */ 00025 00031 #ifndef _GG_Texture_h_ 00032 #define _GG_Texture_h_ 00033 00034 #include <GG/Base.h> 00035 #include <GG/Exception.h> 00036 00037 #include <boost/serialization/access.hpp> 00038 #include <boost/serialization/binary_object.hpp> 00039 00040 00041 namespace GG { 00042 00065 class GG_API Texture 00066 { 00067 public: 00069 Texture(); 00070 virtual ~Texture(); 00071 00072 00074 std::string Filename() const; 00075 GLenum WrapS() const; 00076 GLenum WrapT() const; 00077 GLenum MinFilter() const; 00078 GLenum MagFilter() const; 00079 unsigned int BytesPP() const; 00080 X Width() const; 00081 Y Height() const; 00082 bool MipMapped() const; 00083 GLuint OpenGLId() const; 00084 const GLfloat* DefaultTexCoords() const; 00085 X DefaultWidth() const; 00086 Y DefaultHeight() const; 00087 00090 void OrthoBlit(const Pt& pt1, const Pt& pt2, const GLfloat* tex_coords = 0) const; 00091 00094 void OrthoBlit(const Pt& pt) const; 00096 00098 // intialization functions 00102 void Load(const std::string& filename, bool mipmap = false); 00103 00108 void Init(X width, Y height, const unsigned char* image, GLenum format, GLenum type, 00109 unsigned bytes_per_pixel, bool mipmap = false); 00110 00115 void Init(X x, Y y, X width, Y height, X image_width, 00116 const unsigned char* image, GLenum format, GLenum type, 00117 unsigned int bytes_per_pixel, bool mipmap = false); 00118 00119 void SetWrap(GLenum s, GLenum t); 00120 void SetFilters(GLenum min, GLenum mag); 00121 void Clear(); 00122 00123 00125 00126 GG_ABSTRACT_EXCEPTION(Exception); 00127 00129 GG_CONCRETE_EXCEPTION(BadFile, GG::Texture, Exception); 00130 00132 GG_CONCRETE_EXCEPTION(InvalidColorChannels, GG::Texture, Exception); 00133 00135 GG_CONCRETE_EXCEPTION(InsufficientResources, GG::Texture, Exception); 00137 00138 private: 00139 Texture(const Texture& rhs); 00140 Texture& operator=(const Texture& rhs); 00141 void InitFromRawData(X width, Y height, const unsigned char* image, GLenum format, GLenum type, 00142 unsigned int bytes_per_pixel, bool mipmap); 00143 unsigned char* GetRawBytes(); 00144 00145 std::string m_filename; 00146 00147 unsigned int m_bytes_pp; 00148 X m_width; 00149 Y m_height; 00150 00151 GLenum m_wrap_s, m_wrap_t; 00152 GLenum m_min_filter, m_mag_filter; 00153 00154 bool m_mipmaps; 00155 GLuint m_opengl_id; 00156 GLenum m_format; 00157 GLenum m_type; 00158 00160 GLfloat m_tex_coords[4]; 00161 X m_default_width; 00162 Y m_default_height; 00163 00164 friend class boost::serialization::access; 00165 template <class Archive> 00166 void serialize(Archive& ar, const unsigned int version); 00167 }; 00168 00171 class GG_API SubTexture 00172 { 00173 public: 00175 SubTexture(); 00176 00181 SubTexture(const boost::shared_ptr<const Texture>& texture, X x1, Y y1, X x2, Y y2); 00182 00183 SubTexture(const SubTexture& rhs); 00184 const SubTexture& operator=(const SubTexture& rhs); 00185 virtual ~SubTexture(); 00186 00187 00189 bool Empty() const; 00190 const GLfloat* TexCoords() const; 00191 X Width() const; 00192 Y Height() const; 00193 const Texture* GetTexture() const; 00194 00197 void OrthoBlit(const Pt& pt1, const Pt& pt2) const; 00198 00201 void OrthoBlit(const Pt& pt) const; 00203 00205 00206 GG_ABSTRACT_EXCEPTION(Exception); 00207 00210 GG_CONCRETE_EXCEPTION(BadTexture, GG::SubTexture, Exception); 00211 00214 GG_CONCRETE_EXCEPTION(InvalidTextureCoordinates, GG::SubTexture, Exception); 00216 00217 private: 00218 boost::shared_ptr<const Texture> m_texture; 00219 X m_width; 00220 Y m_height; 00221 GLfloat m_tex_coords[4]; 00222 00223 friend class boost::serialization::access; 00224 template <class Archive> 00225 void serialize(Archive& ar, const unsigned int version); 00226 }; 00227 00236 class GG_API TextureManager 00237 { 00238 public: 00240 00244 boost::shared_ptr<Texture> StoreTexture(Texture* texture, const std::string& texture_name); 00245 00250 boost::shared_ptr<Texture> StoreTexture(const boost::shared_ptr<Texture>& texture, const std::string& texture_name); 00251 00255 boost::shared_ptr<Texture> GetTexture(const std::string& name, bool mipmap = false); 00256 00260 void FreeTexture(const std::string& name); 00262 00263 private: 00264 TextureManager(); 00265 boost::shared_ptr<Texture> LoadTexture(const std::string& filename, bool mipmap); 00266 00267 static bool s_created; 00268 static bool s_il_initialized; 00269 std::map<std::string, boost::shared_ptr<Texture> > m_textures; 00270 00271 friend TextureManager& GetTextureManager(); 00272 }; 00273 00275 TextureManager& GetTextureManager(); 00276 00277 } // namespace GG 00278 00279 // template implementations 00280 template <class Archive> 00281 void GG::Texture::serialize(Archive& ar, const unsigned int version) 00282 { 00283 ar & BOOST_SERIALIZATION_NVP(m_filename) 00284 & BOOST_SERIALIZATION_NVP(m_bytes_pp) 00285 & BOOST_SERIALIZATION_NVP(m_width) 00286 & BOOST_SERIALIZATION_NVP(m_height) 00287 & BOOST_SERIALIZATION_NVP(m_wrap_s) 00288 & BOOST_SERIALIZATION_NVP(m_wrap_t) 00289 & BOOST_SERIALIZATION_NVP(m_min_filter) 00290 & BOOST_SERIALIZATION_NVP(m_mag_filter) 00291 & BOOST_SERIALIZATION_NVP(m_mipmaps) 00292 & BOOST_SERIALIZATION_NVP(m_format) 00293 & BOOST_SERIALIZATION_NVP(m_type) 00294 & BOOST_SERIALIZATION_NVP(m_tex_coords) 00295 & BOOST_SERIALIZATION_NVP(m_default_width) 00296 & BOOST_SERIALIZATION_NVP(m_default_height); 00297 00298 unsigned char* raw_data_bytes = 0; 00299 std::size_t raw_data_size = 0; 00300 if (Archive::is_saving::value) { 00301 if (m_filename == "" && m_opengl_id) 00302 raw_data_bytes = GetRawBytes(); 00303 if (raw_data_bytes) 00304 raw_data_size = static_cast<std::size_t>(Value(m_width) * Value(m_height) * m_bytes_pp); 00305 } 00306 ar & BOOST_SERIALIZATION_NVP(raw_data_size); 00307 if (raw_data_size) { 00308 if (Archive::is_loading::value) { 00309 typedef unsigned char uchar; 00310 raw_data_bytes = new uchar[raw_data_size]; 00311 } 00312 boost::serialization::binary_object raw_data(raw_data_bytes, raw_data_size); 00313 ar & BOOST_SERIALIZATION_NVP(raw_data); 00314 } 00315 00316 if (Archive::is_loading::value) { 00317 if (raw_data_size) { 00318 Init(X0, Y0, m_default_width, m_default_height, m_width, raw_data_bytes, m_format, m_type, m_bytes_pp, m_mipmaps); 00319 } else { 00320 try { 00321 Load(m_filename); 00322 } catch (const BadFile& e) { 00323 // take no action; the Texture must have been uninitialized when saved 00324 } 00325 } 00326 SetWrap(m_wrap_s, m_wrap_t); 00327 SetFilters(m_min_filter, m_mag_filter); 00328 } 00329 00330 if (raw_data_size) 00331 delete [] raw_data_bytes; 00332 } 00333 00334 template <class Archive> 00335 void GG::SubTexture::serialize(Archive& ar, const unsigned int version) 00336 { 00337 boost::shared_ptr<Texture> non_const_texture; 00338 if (Archive::is_saving::value) 00339 non_const_texture = boost::const_pointer_cast<Texture>(m_texture); 00340 00341 ar & boost::serialization::make_nvp("m_texture", non_const_texture) 00342 & BOOST_SERIALIZATION_NVP(m_width) 00343 & BOOST_SERIALIZATION_NVP(m_height) 00344 & BOOST_SERIALIZATION_NVP(m_tex_coords); 00345 00346 if (Archive::is_loading::value) 00347 m_texture = boost::const_pointer_cast<const Texture>(non_const_texture); 00348 } 00349 00350 #endif // _GG_Texture_h_