00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
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
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 }
00278
00279
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
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_