From 3264ac439095b9bdde0375d8a9f9f4445babf839 Mon Sep 17 00:00:00 2001 From: Perttu Ahola Date: Thu, 17 Feb 2011 19:07:14 +0200 Subject: [PATCH] Better texture handling. Textures are not added to atlas if they are big, and atlas is not further made after it is full. --- data/mineral_coal.png | Bin 1620 -> 952 bytes data/mineral_iron.png | Bin 1616 -> 1614 bytes src/main.cpp | 2 +- src/tile.cpp | 191 +++++++++++++++++++++++++++++++++++------- 4 files changed, 160 insertions(+), 33 deletions(-) diff --git a/data/mineral_coal.png b/data/mineral_coal.png index 58a4d2b7959a849ae1e347346fd141ac5ae44b48..3ff9692fb483347662c6b1aa37ff7214d1bd125d 100644 GIT binary patch delta 146 zcmV;D0B!%&47dldF9Ux7b4f%&R5;7ck}(dzAPfVYHSh48|G$HocVtZ`B%o=lswNF8`;DMY_T)RUOVfhuyAbHW)R4 zuSv4+&nb|Mqh#a^SjNEJ*T(#~NOHFa%iFpEU5+`6oCD@m000UA07*qoM6N<$f<5^| AC;$Ke delta 819 zcmV-31I+xm2hv@4Xc+Mbr4_Vmzm zyl^gH_FTOe@AEuwK6%Ak@4U^%t#x97Aihu#uPh^bWD3Q*>{frP*up00@zE=T(Q2|= zu3?%6jeUc#8lcA)@G|+-G`eNt>+2_9F7d!J&9)o{_VLFz>>e6M$=kp!%FMji_128{7FEZ(0kW`OC*Rq^UzQ|wsA^_*k z&0^Rt@#5SWVRzc-4IRDJMs>UK`~8GfKbz$u;iE|;!|8J4`mY>px_I#tfOF#H31M~| zy!`>Htum_Oqh^@=nOz|ki4qG3kj92bICg$abUGbIv{8S){&InW;wKPP*>CUB?b=-V z`Gx~<=RrYy{Bcp<-lEoQA+>7vQDeg_T>9h?ti~1;9?bveP+GtJ@9xguLcH?YSyE4? zXtrC7YH>dPbm36Y+^c5=W{2&aGA@^k(%nsBLkX^~t~jZuCxp0g;Z2&R;Y1WaYsF1b zZd4eO6}*3nN+J=bPaYtkDrDEv_y)q*T~Pe}nC%W;cRx}*afFXP{NTSr2Vmy8anW}5 z;17lomPI=K8-gAdzgm2F-Q=+;_N}%M@4f#nJ$9Fd(ITJEGxx%2mX@y&7}9XNJ$&)m z=MPN>S=8%wj?YdDsjlnT*jO!-qsbK4Z{Eam1jB!!5c#blr(S+Z3sM7l8~aYD1*TePOl&m zevIzEBd%S$`p6KEEQ!I;5M3LVR(=vABcn*Sas_hv4W_4_VPo|b5J3O{002ovPDHLkV1kpjqip~H diff --git a/data/mineral_iron.png b/data/mineral_iron.png index 9698aa0060e42df0d33f8e8e6994b377aa1d4988..51b15d95da3315794e1bd43d8a47b0de6f1609a3 100644 GIT binary patch delta 812 zcmV+{1JnG_49*O&Fav)HNkln3S#lAGqf zE+SP#A2^(|IERPx;}P$F_yNTSMgFbuv`)3z#1Rft-VkmdSiOHP)ryH0)X(;m?Ylqo z#ABn%C;rP<5+F-Ps2&i`1i$^h#f0Ba(`s`uzQo@BUx}xZxZPe9M+%DN0s+-c zt5xC;{gUVmx;#3cYVmihb!=YibHRdILgC&ab4-()l#%GLVj*)N-PpaSxC(hR8?%-W-dO@$KQM@4y+VmuStKDF>R}FV+0H?m41`}Uu$Vm zDVH$2J(QkVLyM(|Y_!(w-!*|g6+sM# zc-B9WJtHG}{U!j_S`*vu%F|(AC?ls&`|_)zWA!K$3cT>#^K@?hz?1b&$>HA&(i}^G zd_G6k$Ou&phzV6eX}4N9I1GCO&M&WU=iWVrQeb~S{f;P<4jBrCZwvdxG!M0AlPg!= zMcvuKJ_TAP;;n11QSQ`v(cU|Qmo>)8`#*(s56g?o^1JVE2qhYeVoXg_a4!it5{ynI zG+O_8xZ2nln>66IIS_Mm^SE+*2dv+`L8sp0kqe91_JCTgL?Rg@=yT!oDnw$_IPOyl qkFO+&`-@k_cJdjaPx%Q4A2a)Fav)JNklAC17U(sKKd^RJ`BZ&fuNw^?A%(5Y))2xkgko%(lpC$(=5Hc z-OZ1?+^;Vpn+!Z~UeD*8BQAV+k+t}A#D2|o?~OCb*3h!u(s-)s4d9Z2;c(|D1u0vSsJ_BJbh>q zC8|c*bN8rjG#P&~P1^hW3=9}_J;{m91vx%`n8#H3PUe91sk7qul^ZBpM5X6>@dN(Nrj(3M+do; zIVn0_NvvO|*|N~oIJ<6#Kl00DQfV@Vj`-lCi>To+-EM!EQFDy1zxsj=7xbit841zt z`J8lqlaH>r92ghg?tPYjx`EQ#-9gKYVBEYUUEquWVnF*J1ONTuTwz@jhh-2-xoV+m zN$N*m7h`6YiMtDr(Uwwk!s>LXZCL~Y0jis2GTBocuP#ae#Y_#cS=*E;HNlmoMRCd5 z6GKszn5us%dg;EzlJ_!V(+&&ctmYe--hPXk(;%s-Z@nd#@4ot@*>?G=i5iyWIij@{U%Cj+R7 s1Y0Hz3)38?>$-RkIs~IZ4#W-q2GyWMg^0-wU;qFB07*qoM6N<$g7addStaticText( L"", - core::rect(100, 70, 100+400, 70+(text_height+5)), + core::rect(0,0,400,text_height+5) + v2s32(100,200), false, false); // Chat text diff --git a/src/tile.cpp b/src/tile.cpp index 24cd9c01..237491aa 100644 --- a/src/tile.cpp +++ b/src/tile.cpp @@ -22,6 +22,65 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "main.h" // for g_settings #include "filesys.h" +/* + Replaces the filename extension. + eg: + std::string image = "a/image.png" + replace_ext(image, "jpg") + -> image = "a/image.jpg" + Returns true on success. +*/ +inline bool replace_ext(std::string &path, const char *ext) +{ + // Find place of last dot, fail if \ or / found. + s32 last_dot_i = -1; + for(s32 i=path.size()-1; i>=0; i--) + { + if(path[i] == '.') + { + last_dot_i = i; + break; + } + + if(path[i] == '\\' || path[i] == '/') + break; + } + // If not found, return an empty string + if(last_dot_i == -1) + return false; + // Else make the new path + path = path.substr(0, last_dot_i+1) + ext; + return true; +} + +/* + Find out the full path of an image by trying different filename + extensions. + + If failed, return "". +*/ +inline std::string getImagePath(std::string path) +{ + // A NULL-ended list of possible image extensions + const char *extensions[] = { + "png", "jpg", "bmp", "tga", "bmp", + "pcx", "ppm", "psd", "wal", "rgb", + NULL + }; + + const char **ext = extensions; + do{ + bool r = replace_ext(path, *ext); + if(r == false) + return ""; + if(fs::PathExists(path)) + return path; + } + while((++ext) != NULL); + + return ""; +} + /* Gets the path to a texture by first checking if the texture exists in texture_path and if not, using the data path. @@ -32,11 +91,16 @@ inline std::string getTexturePath(std::string filename) if(texture_path != "") { std::string fullpath = texture_path + '/' + filename; - if(fs::PathExists(fullpath)) + // Check all filename extensions + fullpath = getImagePath(fullpath); + // If found, return it + if(fullpath != "") return fullpath; } - - return porting::getDataPath(filename.c_str()); + std::string fullpath = porting::getDataPath(filename.c_str()); + // Check all filename extensions + fullpath = getImagePath(fullpath); + return fullpath; } TextureSource::TextureSource(IrrlichtDevice *device): @@ -454,6 +518,25 @@ void TextureSource::buildMainAtlas() } core::dimension2d dim = img2->getDimension(); + + // Don't add to atlas if image is large + core::dimension2d max_size_in_atlas(32,32); + if(dim.Width > max_size_in_atlas.Width + || dim.Height > max_size_in_atlas.Height) + { + dstream<<"INFO: TextureSource::buildMainAtlas(): Not adding " + <<"\""< atlas_dim.Height) + { + dstream<<"WARNING: TextureSource::buildMainAtlas(): " + <<"Atlas is full, not adding more textures." + < dim_base = baseimg->getDimension(); - // Crack will be drawn at this size - u32 cracksize = 16; - // Size of the crack image - core::dimension2d dim_crack(cracksize,cracksize); - // Position to copy the crack from in the crack image - core::position2d pos_other(0, 16 * progression); - - video::IImage *crackimage = driver->createImageFromFile( + + /* + Load crack image. + + It is an image with a number of cracking stages + horizontally tiled. + */ + video::IImage *img_crack = driver->createImageFromFile( getTexturePath("crack.png").c_str()); - if(crackimage) + if(img_crack) { - /*crackimage->copyToWithAlpha(baseimg, v2s32(0,0), - core::rect(pos_other, dim_base), - video::SColor(255,255,255,255), - NULL);*/ - - for(u32 y0=0; y0 dim_crack + = img_crack->getDimension(); + // Count of crack stages + u32 crack_count = dim_crack.Height / dim_crack.Width; + // Limit progression + if(progression > crack_count-1) + progression = crack_count-1; + // Dimension of a single scaled crack stage + core::dimension2d dim_crack_scaled_single( + dim_base.Width, + dim_base.Height + ); + // Dimension of scaled size + core::dimension2d dim_crack_scaled( + dim_crack_scaled_single.Width, + dim_crack_scaled_single.Height * crack_count + ); + // Create scaled crack image + video::IImage *img_crack_scaled = driver->createImage( + video::ECF_A8R8G8B8, dim_crack_scaled); + if(img_crack_scaled) { - // Position to copy the crack to in the base image - core::position2d pos_base(x0*cracksize, y0*cracksize); - crackimage->copyToWithAlpha(baseimg, pos_base, - core::rect(pos_other, dim_crack), - video::SColor(255,255,255,255), - NULL); + // Scale crack image by copying + img_crack->copyToScaling(img_crack_scaled); + + // Position to copy the crack from + core::position2d pos_crack_scaled( + 0, + dim_crack_scaled_single.Height * progression + ); + + // This tiling does nothing currently but is useful + for(u32 y0=0; y0 pos_base( + x0*dim_crack_scaled_single.Width, + y0*dim_crack_scaled_single.Height + ); + // Rectangle to copy the crack from on the scaled image + core::rect rect_crack_scaled( + pos_crack_scaled, + dim_crack_scaled_single + ); + // Copy it + img_crack_scaled->copyToWithAlpha(baseimg, pos_base, + rect_crack_scaled, + video::SColor(255,255,255,255), + NULL); + } + + img_crack_scaled->drop(); } - - crackimage->drop(); + + img_crack->drop(); } } /* @@ -968,7 +1095,7 @@ bool generate_image(std::string part_of_name, video::IImage *& baseimg, pm.buildProjectionMatrixOrthoLH(1.65, 1.65, 0, 100); camera->setProjectionMatrix(pm, true); - scene::ILightSceneNode *light = smgr->addLightSceneNode(0, + /*scene::ILightSceneNode *light =*/ smgr->addLightSceneNode(0, v3f(-50, 100, 0), video::SColorf(0.5,0.5,0.5), 1000); // Render scene @@ -1021,9 +1148,9 @@ void make_progressbar(float value, video::IImage *image) core::dimension2d size = image->getDimension(); - u32 barheight = 1; - u32 barpad_x = 1; - u32 barpad_y = 1; + u32 barheight = size.Height/16; + u32 barpad_x = size.Width/16; + u32 barpad_y = size.Height/16; u32 barwidth = size.Width - barpad_x*2; v2u32 barpos(barpad_x, size.Height - barheight - barpad_y); -- 2.30.2