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
00030 #ifndef _GG_Texture_h_
00031 #define _GG_Texture_h_
00032
00033 #include <GG/Base.h>
00034 #include <GG/Exception.h>
00035
00036 #include <boost/serialization/access.hpp>
00037 #include <boost/serialization/binary_object.hpp>
00038
00039
00040 namespace GG {
00041
00055 class GG_API Texture
00056 {
00057 public:
00059 Texture();
00060 virtual ~Texture();
00061
00062
00064 std::string Filename() const;
00065 GLenum WrapS() const;
00066 GLenum WrapT() const;
00067 GLenum MinFilter() const;
00068 GLenum MagFilter() const;
00069 int BytesPP() const;
00070 GLint Width() const;
00071 GLint Height() const;
00072 bool MipMapped() const;
00073 GLuint OpenGLId() const;
00074 const GLfloat* DefaultTexCoords() const;
00075 GLint DefaultWidth() const;
00076 GLint DefaultHeight() const;
00077
00079 void OrthoBlit(const Pt& pt1, const Pt& pt2, const GLfloat* tex_coords = 0) const;
00080
00082 void OrthoBlit(const Pt& pt) const;
00084
00086
00089 void Load(const std::string& filename, bool mipmap = false);
00090
00093 void Init(int width, int height, const unsigned char* image, GLenum format, GLenum type, int bytes_per_pixel, bool mipmap = false);
00094
00097 void Init(int x, int y, int width, int height, int image_width, const unsigned char* image, GLenum format, GLenum type, int bytes_per_pixel, bool mipmap = false);
00098
00099 void SetWrap(GLenum s, GLenum t);
00100 void SetFilters(GLenum min, GLenum mag);
00101 void Clear();
00102
00103
00105
00106 GG_ABSTRACT_EXCEPTION(Exception);
00107
00109 GG_CONCRETE_EXCEPTION(BadFile, GG::Texture, Exception);
00110
00112 GG_CONCRETE_EXCEPTION(InvalidColorChannels, GG::Texture, Exception);
00113
00115 GG_CONCRETE_EXCEPTION(InsufficientResources, GG::Texture, Exception);
00117
00118 private:
00119 Texture(const Texture& rhs);
00120 Texture& operator=(const Texture& rhs);
00121 void InitFromRawData(int width, int height, const unsigned char* image, GLenum format, GLenum type, int bytes_per_pixel, bool mipmap);
00122 unsigned char* GetRawBytes();
00123
00124 std::string m_filename;
00125
00126 int m_bytes_pp;
00127 GLint m_width;
00128 GLint m_height;
00129
00130 GLenum m_wrap_s, m_wrap_t;
00131 GLenum m_min_filter, m_mag_filter;
00132
00133 bool m_mipmaps;
00134 GLuint m_opengl_id;
00135 GLenum m_format;
00136 GLenum m_type;
00137
00139 GLfloat m_tex_coords[4];
00140 GLint m_default_width;
00141 GLint m_default_height;
00142
00143 friend class boost::serialization::access;
00144 template <class Archive>
00145 void serialize(Archive& ar, const unsigned int version);
00146 };
00147
00149 class GG_API SubTexture
00150 {
00151 public:
00153 SubTexture();
00154
00158 SubTexture(const boost::shared_ptr<const Texture>& texture, int x1, int y1, int x2, int y2);
00159
00160 SubTexture(const SubTexture& rhs);
00161 const SubTexture& operator=(const SubTexture& rhs);
00162 virtual ~SubTexture();
00163
00164
00166 bool Empty() const;
00167 const GLfloat* TexCoords() const;
00168 GLint Width() const;
00169 GLint Height() const;
00170 const Texture* GetTexture() const;
00171
00173 void OrthoBlit(const Pt& pt1, const Pt& pt2) const;
00174
00176 void OrthoBlit(const Pt& pt) const;
00178
00180
00181 GG_ABSTRACT_EXCEPTION(Exception);
00182
00184 GG_CONCRETE_EXCEPTION(BadTexture, GG::SubTexture, Exception);
00185
00187 GG_CONCRETE_EXCEPTION(InvalidTextureCoordinates, GG::SubTexture, Exception);
00189
00190 private:
00191 boost::shared_ptr<const Texture> m_texture;
00192 GLint m_width;
00193 GLint m_height;
00194 GLfloat m_tex_coords[4];
00195
00196 friend class boost::serialization::access;
00197 template <class Archive>
00198 void serialize(Archive& ar, const unsigned int version);
00199 };
00200
00205 class GG_API TextureManager
00206 {
00207 public:
00209
00211 boost::shared_ptr<Texture> StoreTexture(Texture* texture, const std::string& texture_name);
00212
00215 boost::shared_ptr<Texture> StoreTexture(const boost::shared_ptr<Texture>& texture, const std::string& texture_name);
00216
00219 boost::shared_ptr<Texture> GetTexture(const std::string& name, bool mipmap = false);
00220
00223 void FreeTexture(const std::string& name);
00225
00226 static void InitDevIL();
00227
00228 private:
00229 TextureManager();
00230 boost::shared_ptr<Texture> LoadTexture(const std::string& filename, bool mipmap);
00231
00232 static bool s_created;
00233 static bool s_il_initialized;
00234 std::map<std::string, boost::shared_ptr<Texture> > m_textures;
00235
00236 friend TextureManager& GetTextureManager();
00237 };
00238
00240 TextureManager& GetTextureManager();
00241
00242 }
00243
00244
00245 template <class Archive>
00246 void GG::Texture::serialize(Archive& ar, const unsigned int version)
00247 {
00248 ar & BOOST_SERIALIZATION_NVP(m_filename)
00249 & BOOST_SERIALIZATION_NVP(m_bytes_pp)
00250 & BOOST_SERIALIZATION_NVP(m_width)
00251 & BOOST_SERIALIZATION_NVP(m_height)
00252 & BOOST_SERIALIZATION_NVP(m_wrap_s)
00253 & BOOST_SERIALIZATION_NVP(m_wrap_t)
00254 & BOOST_SERIALIZATION_NVP(m_min_filter)
00255 & BOOST_SERIALIZATION_NVP(m_mag_filter)
00256 & BOOST_SERIALIZATION_NVP(m_mipmaps)
00257 & BOOST_SERIALIZATION_NVP(m_format)
00258 & BOOST_SERIALIZATION_NVP(m_type)
00259 & BOOST_SERIALIZATION_NVP(m_tex_coords)
00260 & BOOST_SERIALIZATION_NVP(m_default_width)
00261 & BOOST_SERIALIZATION_NVP(m_default_height);
00262
00263 unsigned char* raw_data_bytes = 0;
00264 std::size_t raw_data_size = 0;
00265 if (Archive::is_saving::value) {
00266 if (m_filename == "" && m_opengl_id)
00267 raw_data_bytes = GetRawBytes();
00268 if (raw_data_bytes)
00269 raw_data_size = static_cast<std::size_t>(m_width * m_height * m_bytes_pp);
00270 }
00271 ar & BOOST_SERIALIZATION_NVP(raw_data_size);
00272 if (raw_data_size) {
00273 if (Archive::is_loading::value) {
00274 typedef unsigned char uchar;
00275 raw_data_bytes = new uchar[raw_data_size];
00276 }
00277 boost::serialization::binary_object raw_data(raw_data_bytes, raw_data_size);
00278 ar & BOOST_SERIALIZATION_NVP(raw_data);
00279 }
00280
00281 if (Archive::is_loading::value) {
00282 if (raw_data_size) {
00283 Init(0, 0, m_default_width, m_default_height, m_width, raw_data_bytes, m_format, m_type, m_bytes_pp, m_mipmaps);
00284 } else {
00285 try {
00286 Load(m_filename);
00287 } catch (const BadFile& e) {
00288
00289 }
00290 }
00291 SetWrap(m_wrap_s, m_wrap_t);
00292 SetFilters(m_min_filter, m_mag_filter);
00293 }
00294
00295 if (raw_data_size)
00296 delete [] raw_data_bytes;
00297 }
00298
00299 template <class Archive>
00300 void GG::SubTexture::serialize(Archive& ar, const unsigned int version)
00301 {
00302 boost::shared_ptr<Texture> non_const_texture;
00303 if (Archive::is_saving::value)
00304 non_const_texture = boost::const_pointer_cast<Texture>(m_texture);
00305
00306 ar & boost::serialization::make_nvp("m_texture", non_const_texture)
00307 & BOOST_SERIALIZATION_NVP(m_width)
00308 & BOOST_SERIALIZATION_NVP(m_height)
00309 & BOOST_SERIALIZATION_NVP(m_tex_coords);
00310
00311 if (Archive::is_loading::value)
00312 m_texture = boost::const_pointer_cast<const Texture>(non_const_texture);
00313 }
00314
00315 #endif // _GG_Texture_h_