I need advice on subject of memory usage optimization

dullman

Villager
Member
Joined
Jun 7, 2015
Messages
20
Reaction score
0
Primarily Uses
Hello i made for myself plugin named dynamic sprite (or equipment depend on version), what it does is basically creating and coloring bitmap through usage of render texture and shaders from pieces of body/equipment, but the first version was working on sprite character class and it created every time bitmap every time map was reloaded (which takes for ~25 actors equipped about 2sec) so every time we go in and out of menu it would mean wait time, first i tried to make version when we have information stored in png file, but truthfully whilst saving to file goes fine but i had a problem with retrieving information from file on correct time (means even with callback in saving files it loaded previous file for me), also since i didn't need cache for those bitmaps at all i create a modified copy of loading bitmap, but in game it was visible lag while loading bitmap and as i said using cache was out of question since i couldn't find a reliable information to inform game when it need to reload reload texture from hdd and when from cache. The last version of mine use a mine cache which keeps all actors current bitmaps and just recreate them when needed, but my spritesheet are 640x420, so basically it's 1mb in memory, so if i have a small game it's acceptable but with larger ones (with ~500 actors) it's not useful. So i come to forum to ask if anyone has a good idea how to optimize this script? 
 

Zalerinian

Jack of all Errors
Veteran
Joined
Dec 17, 2012
Messages
4,696
Reaction score
935
First Language
English
Primarily Uses
N/A
Well first off, that three sentence blob was a little hard to read. Next time, please try spacing separate ideas out more so it's easier to understand. 


Without being able to see the script in question, it's hard to know how to make it better, but images are big, and that's a fact we have to live with. Most images you'll use in a game are pngs, which are compressed without losing data, so you probably aren't using the full megabyte of memory to store the character sheet. If processing your characters to produce the right image takes too much processing, caching is probably your best bet.


Now you say you're using shaders and such for creating these images, so I assume you have a decent handle on what you're doing, but unless you're processing something incredibly complex, I find it hard that a gpu is taking two seconds to finish processing and rendering 25 character sprites. In recent, very unoptimized tests of my own, I've been drawing images larger than the screen multiple times with a frame rate of approximately 35-40, so I am curious as to what is it that you're doing that's causing so much lag. 
 

dullman

Villager
Member
Joined
Jun 7, 2015
Messages
20
Reaction score
0
Primarily Uses
Now you say you're using shaders and such for creating these images, so I assume you have a decent handle on what you're doing, but unless you're processing something incredibly complex, I find it hard that a gpu is taking two seconds to finish processing and rendering 25 character sprites. In recent, very unoptimized tests of my own, I've been drawing images larger than the screen multiple times with a frame rate of approximately 35-40, so I am curious as to what is it that you're doing that's causing so much lag. 
hmm you say you are drawing?? If you are do only this it's understandable why you say it's possible to draw it without loosing much optimization, in my case I could copy and create multi layered sprites from images without needing using shaders, if i added recoloring sprite to do it takes two second for a lone sprites, so basically using shaders is much faster for me than non using. Also similar result i performance i get on unity also using shaders with slightly bigger bitmap, so i believe it's something that either i had problem with understanding how to use properly shaders or it's probably the fastest that i can do.


As for code I was thinking about showing but as it takes 700 lines of code so i show only how i create bitmap since it the most important thing:

Code:
Game_Actor.prototype.SetPoseBitmap = function (poseId) {

    var actor1 = this;
    var entries = this.getSpriteEntries($dataCharAnim[poseId]);
    //console.log(entries);
    var fs = require('fs');
    path = StorageManager.localPathToDynSprite();
    this._counter = 0;

    $ActorPose.bitmaps[actor1._actorId] = new Bitmap(1, 1);
    $ActorPose.itemBitmaps[actor1._actorId] = [];
    var colors = [];
    var transparent = [];
    index = 0;
    function hexToRGB(hex) {
        var bigint = parseInt(hex, 16);
        var r = (bigint >> 16) & 255;
        var g = (bigint >> 8) & 255;
        var b = bigint & 255;
        return [r / 255, g / 255, b / 255];
    }
    var amountOfBitmaps = 0
    for (key in entries) {
        var list = entries[key];
        for (var i = 0; i < list.length; i++) {
            if (fs.existsSync(path + list[i].folderName + "" + list[i].layerSpritePath + ".png")) {
                amountOfBitmaps++;
            }
        }
    }

    $ActorPose.renderTex[actor1._actorId] = null;
    $ActorPose.container[actor1._actorId] = new PIXI.Container();

    for (key in entries) {
        var list = entries[key];
        for (var i = 0; i < list.length; i++) {
            if (fs.existsSync(path + list[i].folderName + "" + list[i].layerSpritePath + ".png")) {
                $ActorPose.itemBitmaps[actor1._actorId][index] = ImageManager.LoadDynamicSprite(list[i].folderName, list[i].layerSpritePath);
                colors[index] = list[i].colors;
                transparent[index] = list[i].transparent;
                index++;
                this._counter++;
                $ActorPose.itemBitmaps[actor1._actorId][index - 1].addLoadListener(function () {
                    this._counter--;
                    //var renderTex = null

                    if (this._counter === 0 && $ActorPose.itemBitmaps[actor1._actorId].length === amountOfBitmaps) {
                        for (var j = 0; j < $ActorPose.itemBitmaps[actor1._actorId].length; j++) {
                            var bit = $ActorPose.itemBitmaps[actor1._actorId][j];
                            if (bit) {
                                if (!$ActorPose.renderTex[actor1._actorId]) {
                                    $ActorPose.renderTex[actor1._actorId] = PIXI.RenderTexture.create(bit.width, bit.height)
                                    //console.log(bit.width);
                                }

                                var usedColors = [];
                                var newColors = [];
                                for (var i = 0; i < 10; i++) {
                                    if (colors[j] && colors[j].UsedColors && colors[j].UsedColors.length > i) {
                                        usedColors.push(new Float32Array(hexToRGB(colors[j].UsedColors[i])));
                                        newColors.push(new Float32Array(hexToRGB(colors[j].NewColors[i])));
                                    } else {
                                        usedColors.push(new Float32Array(1, 1, 1));
                                        newColors.push(new Float32Array(1, 1, 1));
                                    }
                                }

                                var text = bit._baseTexture;
                                var texture = new PIXI.Texture(text);
                                var mySprite = new PIXI.Sprite(texture);
                                var shader = new ChangeColorPallete(usedColors, newColors, 0.00001);

                                mySprite.filters = [shader];

                                if (transparent[j]) {
                                    var pixels = Graphics._renderer.extract.canvas($ActorPose.renderTex[actor1._actorId]);
                                    $ActorPose.bitmaps[actor1._actorId]._context.drawImage(pixels, 0, 0);
                                    $ActorPose.container[actor1._actorId].removeChildren();
                                    $ActorPose.container[actor1._actorId].addChild(mySprite);
                                    Graphics._renderer.render($ActorPose.container[actor1._actorId], $ActorPose.renderTex[actor1._actorId], true);
                                    var pixels = Graphics._renderer.extract.canvas($ActorPose.renderTex[actor1._actorId]);
                                    $ActorPose.bitmaps[actor1._actorId]._context.drawImage(pixels, 0, 0);
                                    $ActorPose.container[actor1._actorId].removeChildren();
                                } else {
                                    $ActorPose.container[actor1._actorId].addChild(mySprite);
                                    Graphics._renderer.render($ActorPose.container[actor1._actorId], $ActorPose.renderTex[actor1._actorId], true);
                                }
                                if ($ActorPose.bitmaps[actor1._actorId].height == 1) {
                                    $ActorPose.bitmaps[actor1._actorId] = new Bitmap(bit.width, bit.height);

                                }

                            }
                            if (amountOfBitmaps - 1 === j) {
                                var pixels = Graphics._renderer.extract.canvas($ActorPose.renderTex[actor1._actorId]);
                                $ActorPose.bitmaps[actor1._actorId]._context.drawImage(pixels, 0, 0);
                                StorageManager.saveDynamicSprite($ActorPose.bitmaps[actor1._actorId], this.currentBitmapPath, this);
                                //$ActorPose.getBitmap(actor1._actorId) = bitmap;
                                //$ActorPose.bitmaps[actor1._actorId] = bitmap;
                                //console.log(actor1._actorId)
                                $ActorPose.itemBitmaps[actor1._actorId] = [];
                                $ActorPose.renderTex[actor1._actorId] = null;
                                $ActorPose.container[actor1._actorId] = null;
                                this.refreshed = true;
                                this.needRefresh = false;
                                this.beingRefreshed = false;
                            }
                        }
                    }
                }.bind(this));
            }
        }
    }
}
 

Users Who Are Viewing This Thread (Users: 0, Guests: 1)

Latest Threads

Latest Profile Posts

Don't forget, aspiring writers: Personality isn't what your characters do, it is WHY they do it.
Hello! I would like to know if there are any pluggings or any way to customize how battles look?
I was thinking that when you start the battle for it to appear the eyes of your characters and opponents sorta like Ace Attorney.
Sadly I don't know how that would be possible so I would be needing help! If you can help me in any way I would really apreciate it!
The biggest debate we need to complete on which is better, Waffles or Pancakes?
rux
How is it going? :D
Day 9 of giveaways! 8 prizes today :D

Forum statistics

Threads
106,051
Messages
1,018,549
Members
137,837
Latest member
Dabi
Top