void DefinitionFile::LoadPNG(const String & _filename, const String & pathToProcess)
{
	String path;
	String name;
	CommandLineParser::SplitFilePath(_filename, path, name);
	String nameWithoutExt = name.substr(0, name.length() - 4);
	String corespondingPngImage = path + String("/") + nameWithoutExt + String(".png");

	filename = pathToProcess + String("/") + nameWithoutExt + String(".txt");
	frameCount = 1;

	PngImageExt image;
	image.Read(corespondingPngImage.c_str());
	spriteWidth = image.GetWidth();
	spriteHeight = image.GetHeight();

	frameRects = new Rect2i[1];
	frameRects[0].x = 0;
	frameRects[0].y = 0;
	frameRects[0].dx = spriteWidth;
	frameRects[0].dy = spriteHeight;

	String fileWrite = pathToProcess + String("/") + nameWithoutExt + "0" + String(".png"); 
	FileSystem::Instance()->CopyFile(_filename, fileWrite);
}
Beispiel #2
0
void TexturePacker::PackToMultipleTextures(const char * excludeFolder, const char* outputPath, std::list<DefinitionFile*> & defList)
{
    if (defList.size() != 1)
        if (CommandLineParser::Instance()->GetVerbose())printf("* ERROR: failed to pack to multiple textures\n");

    for (int i = 0; i < (int)sortVector.size(); ++i)
    {
        DefinitionFile * defFile = sortVector[i].defFile;
        int frame = sortVector[i].frameIndex;
        if (CommandLineParser::Instance()->GetVerbose())printf("[MultiPack] prepack: %s frame: %d w:%d h:%d\n", defFile->filename.c_str(), frame, defFile->frameRects[frame].dx, defFile->frameRects[frame].dy);
    }

    std::vector<ImagePacker*> & packers = usedPackers;

    /*
    // OLD PACKING ALGORITHM
    ImagePacker * currentPacker = new ImagePacker(Rect2i::Make(0, 0, 1024, 1024));
    packers.push_back(currentPacker);

    // Packing of sorted by size images
    for (int i = 0; i < sortVector.size(); ++i)
    {
    	DefinitionFile * defFile = sortVector[i].defFile;
    	int frame = sortVector[i].frameIndex;
    	printf("[MultiPack] pack: %s frame: %d w:%d h:%d\n", defFile->filename.c_str(), frame, defFile->frameRects[frame].dx, defFile->frameRects[frame].dy);

    	bool packed = false;
    	for (int packerIndex = 0; packerIndex < packers.size(); ++packerIndex)
    	{
    		if (packers[packerIndex]->AddImage(Size2i::Make(defFile->frameRects[frame].dx, defFile->frameRects[frame].dy), &defFile->frameRects[frame]))
    		{
    			packed = true;
    			printf("[MultiPack] added to packer: %d\n", packerIndex);
    			break;
    		}
    	}

    	if (!packed)
    	{
    		currentPacker = new ImagePacker(Rect2i::Make(0, 0, 1024, 1024));
    		packers.push_back(currentPacker);

    		if (!currentPacker->AddImage(Size2i::Make(defFile->frameRects[frame].dx, defFile->frameRects[frame].dy), &defFile->frameRects[frame]))
    		{
    			printf("*** FATAL ERROR: image is too big: imageSize: %d, %d\n", defFile->frameRects[frame].dx, defFile->frameRects[frame].dy);
    			return;
    		}else
    		{
    			printf("[MultiPack] added to packer: %d\n", packers.size() - 1);
    		}
    	}

    } */


    /* // ALGO #2
    std::vector<SizeSortItem> sortVectorWork = sortVector;

    while(sortVectorWork.size() > 0)
    {
    	// try to pack for each resolution
    	int maxPackedObjects = 0;
    	//int bestResolution = 1025 * 1025;

    	printf("* Packing tries started: ");

    	ImagePacker * bestPackerForThisStep = 0;
    	std::vector<SizeSortItem> newWorkVector;

    	for (int yResolution = 8; yResolution <= 1024; yResolution *= 2)
    		for (int xResolution = 8; xResolution <= 1024; xResolution *= 2)
    		{
    			Rect2i textureRect = Rect2i::Make(0, 0, xResolution, yResolution);
    			ImagePacker * packer = new ImagePacker(textureRect);

    			std::vector<SizeSortItem> tempSortVector = sortVectorWork;
    			int n = TryToPackFromSortVector(packer, tempSortVector);

    			if (n > maxPackedObjects)
    			{
    				maxPackedObjects = n;
    				SafeDelete(bestPackerForThisStep);
    				bestPackerForThisStep = packer;
    				newWorkVector = tempSortVector;
    			}
    		}

    	sortVectorWork = newWorkVector;
    	packers.push_back(bestPackerForThisStep);
    } */

    std::vector<SizeSortItem> sortVectorWork = sortVector;

    while(sortVectorWork.size() > 0)
    {
        // try to pack for each resolution
        float maxValue = 0.0f;
        //int bestResolution = 1025 * 1025;

        if (CommandLineParser::Instance()->GetVerbose())printf("* Packing tries started: ");

        ImagePacker * bestPackerForThisStep = 0;
        std::vector<SizeSortItem> newWorkVector;

        for (int yResolution = 8; yResolution <= maxTextureSize; yResolution *= 2)
            for (int xResolution = 8; xResolution <= maxTextureSize; xResolution *= 2)
            {
                if (CommandLineParser::Instance()->IsFlagSet("--pvr") && (xResolution != yResolution))continue;

                if ((onlySquareTextures) && (xResolution != yResolution))continue;

                Rect2i textureRect = Rect2i(0, 0, xResolution, yResolution);
                ImagePacker * packer = new ImagePacker(textureRect);

                std::vector<SizeSortItem> tempSortVector = sortVectorWork;
                float n = TryToPackFromSortVectorWeight(packer, tempSortVector);

                if (n > maxValue)
                {
                    maxValue = n;
                    SafeDelete(bestPackerForThisStep);
                    bestPackerForThisStep = packer;
                    newWorkVector = tempSortVector;
                }
            }

        sortVectorWork = newWorkVector;
        packers.push_back(bestPackerForThisStep);
    }

    if (CommandLineParser::Instance()->GetVerbose())printf("* Writing %d final textures \n", (int)packers.size());

    std::vector<PngImageExt*> finalImages;

    for (int imageIndex = 0; imageIndex < (int)packers.size(); ++imageIndex)
    {
        PngImageExt * image = new PngImageExt();
        ImagePacker * packer = packers[imageIndex];
        image->Create(packer->GetRect().dx, packer->GetRect().dy);
        finalImages.push_back(image);
    }

    for (std::list<DefinitionFile*>::iterator defi = defList.begin(); defi != defList.end(); ++defi)
    {
        DefinitionFile * defFile = *defi;

        for (int frame = 0; frame < defFile->frameCount; ++frame)
        {
            Rect2i * destRect;
            ImagePacker * foundPacker = 0;
            int packerIndex = 0;
            char name[256];

            for (packerIndex = 0; packerIndex < (int)packers.size(); ++packerIndex)
            {
                destRect = packers[packerIndex]->SearchRectForPtr(&defFile->frameRects[frame]);

                if (destRect)
                {
                    foundPacker = packers[packerIndex];
                    std::string withoutExt = defFile->filename.substr(0, defFile->filename.length() - 4);
                    snprintf(name, 256, "%s%d.png", withoutExt.c_str(), frame);
                    break;
                }
            }

            if (foundPacker)
            {
                if (CommandLineParser::Instance()->GetVerbose())printf("[MultiPack] pack to texture: %d\n", packerIndex);
                PngImageExt image;
                image.Read(name);
                finalImages[packerIndex]->DrawImage(destRect->x, destRect->y, &image);
                if (CommandLineParser::Instance()->IsFlagSet("--debug"))
                {
                    finalImages[packerIndex]->DrawRect(*destRect, 0xFF0000FF);
                }
            }
        }
    }

    for (int image = 0; image < (int)packers.size(); ++image)
    {
        char temp[256];
        sprintf(temp, "texture%d.png", image);
        std::string textureName = std::string(outputPath) + std::string(temp);
        finalImages[image]->Write(textureName.c_str());
    }

    for (std::list<DefinitionFile*>::iterator defi = defList.begin(); defi != defList.end(); ++defi)
    {
        DefinitionFile * defFile = *defi;

        std::string textureName = std::string(outputPath) + std::string("texture");
        if (!WriteMultipleDefinition(excludeFolder, outputPath, "texture", defFile))
        {
            printf("* ERROR: failed to write definition\n");
        }
    }
}
Beispiel #3
0
void TexturePacker::PackToTextures(const char * excludeFolder, const char* outputPath, std::list<DefinitionFile*> & defsList)
{
    lastPackedPacker = 0;
    for (std::list<DefinitionFile*>::iterator dfi = defsList.begin(); dfi != defsList.end(); ++dfi)
    {
        DefinitionFile * defFile = *dfi;
        for (int frame = 0; frame < defFile->frameCount; ++frame)
        {
            SizeSortItem sortItem;
            sortItem.imageSize = defFile->frameRects[frame].dx * defFile->frameRects[frame].dy;
            sortItem.defFile = defFile;
            sortItem.frameIndex = frame;
            sortVector.push_back(sortItem);
        }
    }

//	for (int i = 0; i < sortVector.size(); ++i)
//	{
//		DefinitionFile * defFile = sortVector[i].defFile;
//		int frame = sortVector[i].frameIndex;
//		printf("[SinglePack] before sort: %s frame: %d w:%d h:%d\n", defFile->filename.c_str(), frame, defFile->frameRects[frame].dx, defFile->frameRects[frame].dy);
//	}

    std::sort(sortVector.begin(), sortVector.end(), sortFn);

//	for (int i = 0; i < sortVector.size(); ++i)
//	{
//		DefinitionFile * defFile = sortVector[i].defFile;
//		int frame = sortVector[i].frameIndex;
//		printf("[SinglePack] after sort: %s frame: %d w:%d h:%d\n", defFile->filename.c_str(), frame, defFile->frameRects[frame].dx, defFile->frameRects[frame].dy);
//	}

    // try to pack for each resolution
    int bestResolution = (maxTextureSize + 1) * (maxTextureSize + 1);
    int bestXResolution, bestYResolution;

    if (CommandLineParser::Instance()->GetVerbose())
        printf("* Packing tries started: ");

    bool isPvr = false;
    if (CommandLineParser::Instance()->IsFlagSet("--pvr"))
        isPvr = true;

    for (int yResolution = 8; yResolution <= maxTextureSize; yResolution *= 2)
        for (int xResolution = 8; xResolution <= maxTextureSize; xResolution *= 2)
        {
            if ((isPvr) && (xResolution != yResolution))continue;

            if ((onlySquareTextures) && (xResolution != yResolution))continue;

            Rect2i textureRect = Rect2i(0, 0, xResolution, yResolution);

            if (xResolution * yResolution < bestResolution)
                if (TryToPack(textureRect, defsList))
                {
                    bestResolution = xResolution * yResolution;
                    bestXResolution = xResolution;
                    bestYResolution = yResolution;
                }
        }
    if (CommandLineParser::Instance()->GetVerbose())
        printf("\n");
    if (bestResolution != (maxTextureSize + 1) * (maxTextureSize + 1))
    {
        std::string textureName = std::string(outputPath) + std::string("texture");
        if (CommandLineParser::Instance()->GetVerbose())
            printf("* Writing final texture (%d x %d): %s\n", bestXResolution, bestYResolution , textureName.c_str());

        PngImageExt finalImage;
        finalImage.Create(bestXResolution, bestYResolution);

        // Writing
        for (std::list<DefinitionFile*>::iterator dfi = defsList.begin(); dfi != defsList.end(); ++dfi)
        {
            DefinitionFile * defFile = *dfi;
            for (int frame = 0; frame < defFile->frameCount; ++frame)
            {
                Rect2i *destRect = lastPackedPacker->SearchRectForPtr(&defFile->frameRects[frame]);
                if (!destRect)printf("*** ERROR Can't find rect for frame\n");

                char name[256];
                std::string withoutExt = defFile->filename.substr(0, defFile->filename.length() - 4);
                snprintf(name, 256, "%s%d.png", withoutExt.c_str(), frame);

                PngImageExt image;
                image.Read(name);
                finalImage.DrawImage(destRect->x, destRect->y, &image);

                if (CommandLineParser::Instance()->IsFlagSet("--debug"))
                {
                    finalImage.DrawRect(*destRect, 0xFF0000FF);
                }
            }

            if (!WriteDefinition(excludeFolder, outputPath, "texture", defFile))
            {
                printf("* ERROR: failed to write definition\n");
            }
        }
        char textureExtension[5] = "png";
        if (CommandLineParser::Instance()->IsFlagSet("--pvr"))strcpy(textureExtension, "pvr");

        textureName += std::string(".") + textureExtension;
        finalImage.Write(textureName.c_str());
    } else
    {
        //
        PackToMultipleTextures(excludeFolder, outputPath, defsList);
    }
}
Beispiel #4
0
void TexturePacker::PackToTexturesSeparate(const char * excludeFolder, const char* outputPath, std::list<DefinitionFile*> & defsList)
{
    lastPackedPacker = 0;
    int textureIndex = 0;
    for (std::list<DefinitionFile*>::iterator dfi = defsList.begin(); dfi != defsList.end(); ++dfi)
    {
        sortVector.clear();

        DefinitionFile * defFile = *dfi;
        for (int frame = 0; frame < defFile->frameCount; ++frame)
        {
            SizeSortItem sortItem;
            sortItem.imageSize = defFile->frameRects[frame].dx * defFile->frameRects[frame].dy;
            sortItem.defFile = defFile;
            sortItem.frameIndex = frame;
            sortVector.push_back(sortItem);
        }
        std::sort(sortVector.begin(), sortVector.end(), sortFn);


        // try to pack for each resolution
        int bestResolution = (maxTextureSize + 1) * (maxTextureSize + 1);
        int bestXResolution, bestYResolution;

        if (CommandLineParser::Instance()->GetVerbose())
            printf("* Packing tries started: ");

        for (int yResolution = 8; yResolution <= maxTextureSize; yResolution *= 2)
            for (int xResolution = 8; xResolution <= maxTextureSize; xResolution *= 2)
            {
                Rect2i textureRect = Rect2i(0, 0, xResolution, yResolution);

                if (xResolution * yResolution < bestResolution)
                    if (TryToPack(textureRect, defsList))
                    {
                        bestResolution = xResolution * yResolution;
                        bestXResolution = xResolution;
                        bestYResolution = yResolution;
                    }
            }
        if (CommandLineParser::Instance()->GetVerbose())
            printf("\n");
        if (bestResolution != (maxTextureSize + 1) * (maxTextureSize + 1))
        {
            char textureNameWithIndex[50];
            sprintf(textureNameWithIndex, "texture%d", textureIndex++);
            std::string textureName = std::string(outputPath) + std::string(textureNameWithIndex);
            if (CommandLineParser::Instance()->GetVerbose())
                printf("* Writing final texture (%d x %d): %s\n", bestXResolution, bestYResolution , textureName.c_str());

            PngImageExt finalImage;
            finalImage.Create(bestXResolution, bestYResolution);

            // Writing
            for (int frame = 0; frame < defFile->frameCount; ++frame)
            {
                Rect2i *destRect = lastPackedPacker->SearchRectForPtr(&defFile->frameRects[frame]);
                if (!destRect)printf("*** ERROR Can't find rect for frame\n");

                char name[256];
                std::string withoutExt = defFile->filename.substr(0, defFile->filename.length() - 4);
                snprintf(name, 256, "%s%d.png", withoutExt.c_str(), frame);

                PngImageExt image;
                image.Read(name);
                finalImage.DrawImage(destRect->x, destRect->y, &image);
            }

            if (!WriteDefinition(excludeFolder, outputPath, textureNameWithIndex, defFile))
            {
                printf("* ERROR: failed to write definition\n");
            }
            char textureExtension[5] = "png";
            if (CommandLineParser::Instance()->IsFlagSet("--pvr"))strcpy(textureExtension, "pvr");
            textureName += std::string(".") + textureExtension;

            finalImage.Write(textureName.c_str());
        }
    }
}
bool DefinitionFile::LoadPNGDef(const std::string & _filename, const std::string & pathToProcess)
{
	if (CommandLineParser::Instance()->GetVerbose())printf("* Load PNG Definition: %s\n", _filename.c_str()); 
	
	FILE * fp = fopen(_filename.c_str(), "rt");
	fscanf(fp, "%d", &frameCount);

	String path;
	String name;
	CommandLineParser::SplitFilePath(_filename, path, name);
	String nameWithoutExt = name.substr(0, name.length() - 7);
	String corespondingPngImage = path + String("/") + nameWithoutExt + String(".png");

	filename = pathToProcess + String("/") + nameWithoutExt + String(".txt");
	
	PngImageExt image;
	image.Read(corespondingPngImage.c_str());
	spriteWidth = image.GetWidth() / frameCount;
	spriteHeight = image.GetHeight();
	
//	String dirWrite = path + String("/$process/"); 
//	mkdir(dirWrite.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
	if (CommandLineParser::Instance()->GetVerbose())printf("* frameCount: %d spriteWidth: %d spriteHeight: %d\n", frameCount, spriteWidth, spriteHeight); 


	frameRects = new Rect2i[frameCount];
	for (int k = 0; k < frameCount; ++k)
	{
		PngImageExt frameX;
		frameX.Create(spriteWidth, spriteHeight);
		frameX.DrawImage(0, 0, &image, Rect2i(k * spriteWidth, 0, spriteWidth, spriteHeight));
		
		
		Rect2i reducedRect;
		frameX.FindNonOpaqueRect(reducedRect);
		if (CommandLineParser::Instance()->GetVerbose())printf("%s - reduced_rect(%d %d %d %d)\n", nameWithoutExt.c_str(), reducedRect.x, reducedRect.y, reducedRect.dx, reducedRect.dy);
		
		/*if (k == 1)
		{
			for (int y = 0; y < spriteWidth; ++y)
			{
				for (int x = 0; x < spriteWidth; ++x)
				{
					printf("%02x ", frameX.GetPixel(x, y)[3]);
				}
				printf("\n");
			}
		}*/
		
		PngImageExt frameX2;
		frameX2.Create(reducedRect.dx, reducedRect.dy);
		frameX2.DrawImage(0, 0, &frameX, reducedRect);
		
		char number[10];
		sprintf(number, "%d", k);
		String fileWrite = pathToProcess + String("/") + nameWithoutExt + String(number) + String(".png"); 
		frameX2.Write(fileWrite.c_str());		
	
		frameRects[k].x = reducedRect.x;
		frameRects[k].y = reducedRect.y;
		frameRects[k].dx = reducedRect.dx;
		frameRects[k].dy = reducedRect.dy;
	
	
		if (CommandLineParser::Instance()->IsFlagSet("--add0pixel"))
		{
			
		}else if (CommandLineParser::Instance()->IsFlagSet("--add1pixel"))
		{
			frameRects[k].dx++;
			frameRects[k].dy++;
		}
		else if (CommandLineParser::Instance()->IsFlagSet("--add2pixel"))
		{
			frameRects[k].dx+=2;
			frameRects[k].dy+=2;
		}
		else if (CommandLineParser::Instance()->IsFlagSet("--add4pixel"))
		{
			frameRects[k].dx+=4;
			frameRects[k].dy+=4;
		}else 
		{
			frameRects[k].dx++;
			frameRects[k].dy++;	
		}
	}
	

	fclose(fp);
	return true;
}