00001 #include "gui_texture.hpp"
00002
00003 #include "gui_layeredregion.hpp"
00004 #include "gui_manager.hpp"
00005 #include "gui_rendertarget.hpp"
00006 #include "gui_material.hpp"
00007 #include "gui_out.hpp"
00008
00009 #include <utils_filesystem.hpp>
00010 #include <sstream>
00011
00012 namespace gui
00013 {
00014 texture::texture(manager* pManager) : layered_region(pManager),
00015 mBlendMode_(BLEND_NONE), bIsDesaturated_(false), mColor_(color::WHITE),
00016 bTexCoordModifiesRect_(false)
00017 {
00018 lTexCoord_[0] = lTexCoord_[1] = lTexCoord_[3] = lTexCoord_[6] = 0.0f;
00019 lTexCoord_[2] = lTexCoord_[4] = lTexCoord_[5] = lTexCoord_[7] = 1.0f;
00020 lType_.push_back("Texture");
00021 }
00022
00023 texture::~texture()
00024 {
00025 }
00026
00027 std::string texture::serialize(const std::string& sTab) const
00028 {
00029 std::ostringstream sStr;
00030 sStr << layered_region::serialize(sTab);
00031
00032 if (!sTextureFile_.empty())
00033 {
00034 sStr << sTab << " # File : " << sTextureFile_ << "\n";
00035 }
00036 else if (!mGradient_.is_empty())
00037 {
00038 sStr << sTab << " # Gradient :\n";
00039 sStr << sTab << " #-###\n";
00040 sStr << sTab << " | # min color : " << mGradient_.get_min_color() << "\n";
00041 sStr << sTab << " | # max color : " << mGradient_.get_max_color() << "\n";
00042 sStr << sTab << " | # orientation : ";
00043 switch (mGradient_.get_orientation())
00044 {
00045 case gradient::HORIZONTAL : sStr << "HORIZONTAL\n"; break;
00046 case gradient::VERTICAL : sStr << "VERTICAL\n"; break;
00047 default : sStr << "<error>\n"; break;
00048 }
00049 sStr << sTab << " #-###\n";
00050 }
00051 else
00052 {
00053 sStr << sTab << " # Color : " << mColor_ << "\n";
00054 }
00055
00056 sStr << sTab << " # Tex. coord. :\n";
00057 sStr << sTab << " #-###\n";
00058 sStr << sTab << " | # top-left : (" << lTexCoord_[0] << ", " << lTexCoord_[1] << ")\n";
00059 sStr << sTab << " | # top-right : (" << lTexCoord_[2] << ", " << lTexCoord_[3] << ")\n";
00060 sStr << sTab << " | # bottom-right : (" << lTexCoord_[4] << ", " << lTexCoord_[5] << ")\n";
00061 sStr << sTab << " | # bottom-left : (" << lTexCoord_[6] << ", " << lTexCoord_[7] << ")\n";
00062 sStr << sTab << " #-###\n";
00063 sStr << sTab << " # TexCModRect : " << bTexCoordModifiesRect_ << "\n";
00064
00065 sStr << sTab << " # Blend mode : ";
00066 switch (mBlendMode_)
00067 {
00068 case BLEND_NONE : sStr << "NONE\n"; break;
00069 case BLEND_BLEND : sStr << "BLEND\n"; break;
00070 case BLEND_KEY : sStr << "KEY\n"; break;
00071 case BLEND_ADD : sStr << "ADD\n"; break;
00072 case BLEND_MOD : sStr << "MOD\n"; break;
00073 default : sStr << "<error>\n"; break;
00074 }
00075
00076 sStr << sTab << " # Desaturated : " << bIsDesaturated_ << "\n";
00077
00078 return sStr.str();
00079 }
00080
00081 void texture::render()
00082 {
00083 if (pSprite_ && is_visible())
00084 {
00085 pSprite_->render_2v(
00086 lBorderList_[BORDER_LEFT], lBorderList_[BORDER_TOP],
00087 lBorderList_[BORDER_RIGHT], lBorderList_[BORDER_BOTTOM]
00088 );
00089 }
00090 }
00091
00092 void texture::create_glue()
00093 {
00094 utils::wptr<lua::state> pLua = pManager_->get_lua();
00095 pLua->push_string(sName_);
00096 lGlueList_.push_back(pLua->push_new<lua_texture>());
00097 pLua->set_global(sLuaName_);
00098 pLua->pop();
00099 }
00100
00101 void texture::copy_from(uiobject* pObj)
00102 {
00103 uiobject::copy_from(pObj);
00104
00105 texture* pTexture = dynamic_cast<texture*>(pObj);
00106
00107 if (pTexture)
00108 {
00109 std::string sTexture = pTexture->get_texture();
00110 if (sTexture.empty())
00111 {
00112 const gradient& mGradient = pTexture->get_gradient();
00113 if (!mGradient.is_empty())
00114 this->set_gradient(mGradient);
00115 else
00116 this->set_color(pTexture->get_color());
00117 }
00118 else
00119 this->set_texture(sTexture);
00120
00121 this->set_blend_mode(pTexture->get_blend_mode());
00122 this->set_tex_coord(pTexture->get_tex_coord());
00123 this->set_tex_coord_modifies_rect(pTexture->get_tex_coord_modifies_rect());
00124 this->set_desaturated(pTexture->is_desaturated());
00125 }
00126 }
00127
00128 texture::blend_mode texture::get_blend_mode() const
00129 {
00130 return mBlendMode_;
00131 }
00132
00133 const color& texture::get_color() const
00134 {
00135 return mColor_;
00136 }
00137
00138 const gradient& texture::get_gradient() const
00139 {
00140 return mGradient_;
00141 }
00142
00143 const std::array<float,8>& texture::get_tex_coord() const
00144 {
00145 return lTexCoord_;
00146 }
00147
00148 bool texture::get_tex_coord_modifies_rect() const
00149 {
00150 return bTexCoordModifiesRect_;
00151 }
00152
00153 const std::string& texture::get_texture() const
00154 {
00155 return sTextureFile_;
00156 }
00157
00158 color texture::get_vertex_color() const
00159 {
00160 if (pSprite_)
00161 return pSprite_->get_color();
00162 else
00163 {
00164 gui::out << gui::error << "gui::" << lType_.back() << " : "
00165 << "Trying to call get_vertex_color on an uninitialized texture : "+sName_+"." << std::endl;
00166
00167 return color::EMPTY;
00168 }
00169 }
00170
00171 bool texture::is_desaturated() const
00172 {
00173 return bIsDesaturated_;
00174 }
00175
00176 void texture::set_blend_mode(blend_mode mBlendMode)
00177 {
00178 if (mBlendMode_ != mBlendMode)
00179 {
00180 mBlendMode_ = mBlendMode;
00181 notify_renderer_need_redraw();
00182 }
00183 }
00184
00185 void texture::set_blend_mode(const std::string& sBlendMode)
00186 {
00187 blend_mode mOldBlendMode = mBlendMode_;
00188
00189 gui::out << gui::warning << "gui::" << lType_.back() << " : "
00190 << "texture::set_blend_mode is not yet implemented." << std::endl;
00191
00192 if (sBlendMode == "BLEND")
00193 mBlendMode_ = BLEND_BLEND;
00194 else if (sBlendMode == "ADD")
00195 mBlendMode_ = BLEND_ADD;
00196 else if (sBlendMode == "MOD")
00197 mBlendMode_ = BLEND_MOD;
00198 else if (sBlendMode == "KEY")
00199 mBlendMode_ = BLEND_KEY;
00200 else if (sBlendMode == "NONE")
00201 mBlendMode_ = BLEND_NONE;
00202 else
00203 {
00204 gui::out << gui::warning << "gui::" << lType_.back() << " : "
00205 << "Unknown blending : \"" << sBlendMode << "\". Using \"BLEND\"." << std::endl;
00206
00207 mBlendMode_ = BLEND_BLEND;
00208 }
00209
00210 if (mOldBlendMode != mBlendMode_)
00211 notify_renderer_need_redraw();
00212 }
00213
00214 void texture::set_desaturated(bool bIsDesaturated)
00215 {
00216 if (!pSprite_)
00217 {
00218 gui::out << gui::warning << "gui::" << lType_.back() << " : "
00219 << "Trying to desaturate an uninitialized texture : " << sName_ << "." << std::endl;
00220
00221 return;
00222 }
00223
00224 if (bIsDesaturated_ != bIsDesaturated)
00225 {
00226 bIsDesaturated_ = bIsDesaturated;
00227 pSprite_->set_desaturated(bIsDesaturated_);
00228
00229 notify_renderer_need_redraw();
00230 }
00231 }
00232
00233 void texture::set_gradient(const gradient& mGradient)
00234 {
00235 mColor_ = color::EMPTY;
00236 sTextureFile_ = "";
00237 mGradient_ = mGradient;
00238 pSprite_ = pManager_->create_sprite(
00239 pManager_->create_material(color::WHITE), 256, 256
00240 );
00241
00242 if (mGradient_.get_orientation() == gradient::HORIZONTAL)
00243 {
00244 pSprite_->set_color(mGradient_.get_min_color(), 0);
00245 pSprite_->set_color(mGradient_.get_min_color(), 3);
00246 pSprite_->set_color(mGradient_.get_max_color(), 1);
00247 pSprite_->set_color(mGradient_.get_max_color(), 2);
00248 }
00249 else
00250 {
00251 pSprite_->set_color(mGradient_.get_min_color(), 0);
00252 pSprite_->set_color(mGradient_.get_min_color(), 1);
00253 pSprite_->set_color(mGradient_.get_max_color(), 2);
00254 pSprite_->set_color(mGradient_.get_max_color(), 3);
00255 }
00256
00257 notify_renderer_need_redraw();
00258 }
00259
00260 void texture::set_tex_coord(const std::array<float,4>& lCoordinates)
00261 {
00262 if (pSprite_)
00263 {
00264 pSprite_->set_texture_rect(lCoordinates, true);
00265 lTexCoord_ = pSprite_->get_texture_coords(true);
00266 notify_renderer_need_redraw();
00267 }
00268 else
00269 {
00270 gui::out << gui::error << "gui::" << lType_.back() << " : "
00271 << "Trying to call set_tex_coord on an uninitialized texture : " << sName_ << "." << std::endl;
00272 }
00273 }
00274
00275 void texture::set_tex_coord(const std::array<float,8>& lCoordinates)
00276 {
00277 if (pSprite_)
00278 {
00279 pSprite_->set_texture_coords(lCoordinates, true);
00280 lTexCoord_ = lCoordinates;
00281 notify_renderer_need_redraw();
00282 }
00283 else
00284 {
00285 gui::out << gui::error << "gui::" << lType_.back() << " : "
00286 << "Trying to call set_tex_coord on an uninitialized texture : " << sName_ << "." << std::endl;
00287 }
00288 }
00289
00290 void texture::set_tex_coord_modifies_rect(bool bTexCoordModifiesRect)
00291 {
00292 if (bTexCoordModifiesRect_ != bTexCoordModifiesRect)
00293 {
00294 bTexCoordModifiesRect_ = bTexCoordModifiesRect;
00295 notify_renderer_need_redraw();
00296 }
00297 }
00298
00299 void texture::set_texture(const std::string& sFile)
00300 {
00301 mGradient_ = gradient();
00302 mColor_ = color::EMPTY;
00303 sTextureFile_ = sFile;
00304
00305 pSprite_ = nullptr;
00306
00307 if (sTextureFile_ == "")
00308 return;
00309
00310 if (utils::file_exists(sTextureFile_))
00311 {
00312 pSprite_ = pManager_->create_sprite(pManager_->create_material(sTextureFile_));
00313 pSprite_->set_texture_coords(lTexCoord_, true);
00314 }
00315 else
00316 {
00317 gui::out << gui::error << "gui::" << lType_.back() << " : "
00318 << "Cannot find file \"" << sFile << "\" for \"" << sName_
00319 << "\".\nUsing white texture instead." << std::endl;
00320
00321 pSprite_ = pManager_->create_sprite(pManager_->create_material(color::WHITE), 256, 256);
00322 }
00323
00324 notify_renderer_need_redraw();
00325 }
00326
00327 void texture::set_texture(utils::refptr<render_target> pRenderTarget)
00328 {
00329 mGradient_ = gradient();
00330 mColor_ = color::EMPTY;
00331 sTextureFile_ = "";
00332
00333 pSprite_ = nullptr;
00334
00335 if (pRenderTarget)
00336 pSprite_ = pManager_->create_sprite(pManager_->create_material(pRenderTarget));
00337 else
00338 {
00339 gui::out << gui::error << "gui::" << lType_.back() << " : "
00340 << "Cannot create a texture with a null RenterTarget.\n"
00341 "Using white texture instead." << std::endl;
00342
00343 pSprite_ = pManager_->create_sprite(pManager_->create_material(color::WHITE), 256, 256);
00344 }
00345
00346 notify_renderer_need_redraw();
00347 }
00348
00349 void texture::set_color(const color& mColor)
00350 {
00351 mGradient_ = gradient();
00352 sTextureFile_ = "";
00353
00354 mColor_ = mColor;
00355 pSprite_ = pManager_->create_sprite(pManager_->create_material(mColor), 256, 256);
00356
00357 notify_renderer_need_redraw();
00358 }
00359
00360 void texture::set_sprite(utils::refptr<sprite> pSprite)
00361 {
00362 mGradient_ = gradient();
00363 sTextureFile_ = "";
00364
00365 pSprite_ = pSprite;
00366
00367 set_abs_width(pSprite->get_width());
00368 set_abs_height(pSprite->get_height());
00369
00370 lTexCoord_ = pSprite->get_texture_coords(true);
00371
00372 notify_renderer_need_redraw();
00373 }
00374
00375 void texture::set_vertex_color(const color& mColor)
00376 {
00377 if (pSprite_)
00378 {
00379 pSprite_->set_color(mColor);
00380 notify_renderer_need_redraw();
00381 }
00382 else
00383 {
00384 gui::out << gui::error << "gui::" << lType_.back() << " : "
00385 << "Trying to set vertex color of an uninitialized texture : " << sName_ << "." << std::endl;
00386 }
00387 }
00388 }