X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=src%2Ftile.cpp;h=4af7a327273d0059ad32aecdff3416836f6d2132;hb=194258b4794ec13b9ffa7b5f37a3060ecc0e59b3;hp=bc4c49cb1717a548babd6a5204f67c58cdd8e43d;hpb=157a4cf18cb9c098f465b8baecd7d2cd5705f2dd;p=oweals%2Fminetest.git diff --git a/src/tile.cpp b/src/tile.cpp index bc4c49cb1..4af7a3272 100644 --- a/src/tile.cpp +++ b/src/tile.cpp @@ -132,8 +132,9 @@ std::string getTexturePath(const std::string &filename) */ if(fullpath == "") { - std::string rel_path = std::string("clienttextures")+DIR_DELIM+filename; - std::string testpath = porting::path_data + DIR_DELIM + rel_path; + std::string base_path = porting::path_share + DIR_DELIM + "textures" + + DIR_DELIM + "base" + DIR_DELIM + "pack"; + std::string testpath = base_path + DIR_DELIM + filename; // Check all filename extensions. Returns "" if not found. fullpath = getImagePath(testpath); } @@ -278,12 +279,14 @@ public: Example case #2: - Assume a texture with the id 1 exists, and has the name "stone.png^mineral1" and is specified as a part of some atlas. - - Now MapBlock::getNodeTile() stumbles upon a node which uses - texture id 1, and finds out that NODEMOD_CRACK must be applied - with progression=0 - - It finds out the name of the texture with getTextureName(1), + - Now getNodeTile() stumbles upon a node which uses + texture id 1, and determines that MATERIAL_FLAG_CRACK + must be applied to the tile + - MapBlockMesh::animate() finds the MATERIAL_FLAG_CRACK and + has received the current crack level 0 from the client. It + finds out the name of the texture with getTextureName(1), appends "^crack0" to it and gets a new texture id with - getTextureId("stone.png^mineral1^crack0") + getTextureId("stone.png^mineral1^crack0"). */ @@ -336,6 +339,12 @@ public: return ap.atlas; } + // Gets a separate texture atlas pointer + AtlasPointer getTextureRawAP(const AtlasPointer &ap) + { + return getTexture(getTextureName(ap.id) + "^[forcesingle"); + } + // Returns a pointer to the irrlicht device virtual IrrlichtDevice* getDevice() { @@ -474,6 +483,9 @@ u32 TextureSource::getTextureId(const std::string &name) return 0; } +// Overlay image on top of another image (used for cracks) +void overlay(video::IImage *image, video::IImage *overlay); + // Brighten image void brighten(video::IImage *image); @@ -997,7 +1009,7 @@ void TextureSource::buildMainAtlas(class IGameDef *gamedef) /* Write image to file so that it can be inspected */ - /*std::string atlaspath = porting::path_userdata + /*std::string atlaspath = porting::path_user + DIR_DELIM + "generated_texture_atlas.png"; infostream<<"Removing and writing texture atlas for inspection to " <=0; i--) - { - if(name[i] == separator) - { - last_separator_position = i; - break; - } - } + s32 last_separator_position = name.find_last_of(separator); + //if(last_separator_position == std::npos) + // last_separator_position = -1; /*infostream<<"generate_image_from_scratch(): " <<"last_separator_position="< dim_base = baseimg->getDimension(); @@ -1202,65 +1219,56 @@ bool generate_image(std::string part_of_name, video::IImage *& baseimg, */ video::IImage *img_crack = sourcecache->getOrLoad("crack.png", device); - if(img_crack) + if(img_crack && progression >= 0) { // Dimension of original image core::dimension2d dim_crack = img_crack->getDimension(); // Count of crack stages - u32 crack_count = dim_crack.Height / dim_crack.Width; + s32 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 + // Dimension of a single crack stage + core::dimension2d dim_crack_cropped( + dim_crack.Width, + dim_crack.Width ); - // Create scaled crack image + // Create cropped and scaled crack images + video::IImage *img_crack_cropped = driver->createImage( + video::ECF_A8R8G8B8, dim_crack_cropped); video::IImage *img_crack_scaled = driver->createImage( - video::ECF_A8R8G8B8, dim_crack_scaled); - if(img_crack_scaled) + video::ECF_A8R8G8B8, dim_base); + + if(img_crack_cropped && img_crack_scaled) { + // Crop crack image + v2s32 pos_crack(0, progression*dim_crack.Width); + img_crack->copyTo(img_crack_cropped, + v2s32(0,0), + core::rect(pos_crack, dim_crack_cropped)); // 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; y0copyToScaling(img_crack_scaled); + // Copy or overlay crack image + if(use_overlay) { - // Position to copy the crack to in the base image - core::position2d 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); + overlay(baseimg, img_crack_scaled); } + else + { + img_crack_scaled->copyToWithAlpha( + baseimg, + v2s32(0,0), + core::rect(v2s32(0,0), dim_base), + video::SColor(255,255,255,255)); + } + } + if(img_crack_scaled) img_crack_scaled->drop(); - } + + if(img_crack_cropped) + img_crack_cropped->drop(); img_crack->drop(); } @@ -1489,8 +1497,6 @@ bool generate_image(std::string part_of_name, video::IImage *& baseimg, if(rtt == NULL) { - errorstream<<"generate_image(): render to texture failed." - " Creating fallback image"< dim = image->getDimension(); + core::dimension2d dim_overlay = overlay->getDimension(); + assert(dim == dim_overlay); + + for(u32 y=0; ygetPixel(x,y); + video::SColor c2 = overlay->getPixel(x,y); + u32 a1 = c1.getAlpha(); + u32 a2 = c2.getAlpha(); + if(a1 == 255 && a2 != 0) + { + c1.setRed((c1.getRed()*(255-a2) + c2.getRed()*a2)/255); + c1.setGreen((c1.getGreen()*(255-a2) + c2.getGreen()*a2)/255); + c1.setBlue((c1.getBlue()*(255-a2) + c2.getBlue()*a2)/255); + } + image->setPixel(x,y,c1); + } +} + void brighten(video::IImage *image) { if(image == NULL)