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 }