1 /** 2 Copyright: Copyright (c) 2017-2018 Andrey Penechko. 3 License: $(WEB boost.org/LICENSE_1_0.txt, Boost License 1.0). 4 Authors: Andrey Penechko. 5 */ 6 module voxelman.graphics.sprite; 7 8 import dlib.image.io.png; 9 import std.path : setExtension; 10 import std.stdio; 11 import std..string; 12 import std.range : zip; 13 import voxelman.math; 14 import voxelman.graphics; 15 import voxelman.graphics.image.crop; 16 17 SpriteRef loadSprite(string filename, TextureAtlas texAtlas) 18 { 19 string imageFilename = setExtension(filename, "png"); 20 auto image = new Bitmap(loadPNG(imageFilename)); 21 irect atlasRect = putSpriteIntoAtlas(image, irect(0,0,image.width, image.height), texAtlas); 22 return new Sprite(atlasRect); 23 } 24 25 SpriteRef[string] loadNamedSpriteSheet(string filename, TextureAtlas texAtlas, ivec2 spriteSize) 26 { 27 string descriptionFilename = setExtension(filename, "txt"); 28 auto file = File(descriptionFilename); 29 30 SpriteRef[] spriteArray = loadIndexedSpriteSheet(filename, texAtlas, spriteSize); 31 size_t spriteIndex; 32 33 SpriteRef[string] spriteMap; 34 foreach(nameValue; zip(file.byLineCopy(), spriteArray)) 35 { 36 spriteMap[strip(nameValue[0])] = nameValue[1]; 37 } 38 39 return spriteMap; 40 } 41 42 SpriteRef[] loadIndexedSpriteSheet(string filename, TextureAtlas texAtlas, ivec2 spriteSize) 43 { 44 string imageFilename = setExtension(filename, "png"); 45 auto image = new Bitmap(loadPNG(imageFilename)); 46 47 SpriteRef[] sprites; 48 size_t spriteIndex; 49 50 ivec2 imageSize = ivec2(image.width, image.height); 51 ivec2 gridSize = imageSize / spriteSize; 52 sprites.length = gridSize.x * gridSize.y; 53 54 foreach(j; 0..gridSize.y) 55 foreach(i; 0..gridSize.x) 56 { 57 irect spriteSubRect = irect(ivec2(i,j) * spriteSize, spriteSize); 58 cropImage(image, spriteSubRect.position, spriteSubRect.size); 59 60 irect atlasRect = putSpriteIntoAtlas(image, spriteSubRect, texAtlas); 61 sprites[spriteIndex++] = new Sprite(atlasRect); 62 } 63 64 return sprites; 65 } 66 67 irect putSpriteIntoAtlas(Bitmap sourceBitmap, irect spriteRect, TextureAtlas texAtlas) 68 { 69 ivec2 position = texAtlas.insert(sourceBitmap, spriteRect); 70 return irect(position, spriteRect.size); 71 } 72 73 struct Sprite 74 { 75 irect atlasRect; 76 } 77 78 alias SpriteRef = Sprite*; 79 80 struct SpriteInstance 81 { 82 SpriteRef sprite; 83 84 vec2 scale = vec2(1, 1); 85 vec2 origin = vec2(0, 0); 86 }