I want to render a QML subtree manually to a Canvas3D by having all the subtree's items' be-texture-source flag (layer.enabled) enabled, and taking the geometry (x, y, width, height) of each item from the corresponding QML properties of each item (calculated by layouts, anchors, etc), so I know how to position and size each item with OpenGL calls.
I have no problems with implementing this, except for a performance issue: since I'm drawing the items in OpenGL, I don't want Qt to also draw them to the window (this would be doing the same work twice). I could achieve that easily by setting opacity: 0 on the items, but that would probably only fix the visual problem, it wouldn't save performance. I could also set visible: false but then I think the layout components wouldn't be able to do their job correctly.
The reasons I want to implement the described architecture are:
I want to implement custom rendering for some of the items in the subtree, but still use their positions and sizes (calculated by the layout for me) for the custom rendering. This custom rendering is complex enough that it can't be done with QML features alone, and I don't want to use Qt3D.
I could use use another approach: use a separate Canvas3D for every item that I want to render customly. And let Qt Quick render the rest of the items for me normally. That's what I've been doing until now. The problem, however, is that:
The different Canvas3Ds can't share GL resources, so I need to initialize and keep copies of the GL resources in each Canvas3D. This increases load time and memory usage.
The creation time of each Canvas3D (even without my GL init code) is significant, I think
So instead I want to use a single, big Canvas3D.
I see how I can use a statically initialized libgdx table in scrollpane to get a nice short scrolling table.
But I want to be a able to scroll a potentially very large list of items (e.g. pictures with overlayed captions) which needs to load the items at runtime as the scrolling is happening - what is often known as an infinite scroller.
This seems tricky to do because:
There isn't enough GPU memory to store all my items so I need to load/unload dynamically. Not clear how to do this with libgdx. Should I use the asset-manager for this and poll?
Load/unload should happen in a separate thread without interfering with the scrolling animations. For example, some applications show a placeholder image if you scroll too fast.
For performance reasons, it seems I should maintain a single texture of the currently active items. Is there support for runtime packing of this kind?
In iOS, this kind of dynamic scroller is supported by UITableView and dynamic prototypes. Is there something that can simplify this for me for libgdx?
I'm an engineer and we are currently porting our Red5 + Flash game into a Node.js + Easeljs html5 application.
Basicly: it's a board game, not an rpg. The layer system means we have multiple canvasses, based on functionally. For example there is a static background stage, with images. There is a layer for just the timers.
At default, all canvas size is 1920x1080, if needed we downscale to fit to the resolution.
The first approach used kinetic.js, but the performance fallen when the game got complex. Then we switched to easel, because it's abstraction level is lower, so we can decide how to implement some more function, not just use the provided robust one.
I was optimistic, but now it's starting to show slowness again, that's why I want to look deeper inside and do fine performance tuning. (Of course everything is fine in Chrome, Firefox is the problem, but the game must run smoothly on all modern browser).
The main layer (stage) is the map, contains ~30 containers, in each there is a complex custom shape, ~10 images. The containers are listening to mouse events, like mouseover, out, click. Currently, for example on mouseover I refill the shape with gradient.
Somehow, when I use cache, like the way in the tuts the performance get even worse, so I assume I'm messing up something.
I collected some advanced questions:
In the described situation when can I use cache and how? I've already tried cache on init, cacheUpdate after fill with other color or gradient, then stage.update(). No impact.
If I have a static, never changing stage cache doesn't make sense on that layer, right?
What stage.update() exactly do? Triggering the full layer redraw? The doc mentions some kind of intelligent if changed then redraw effect.
If I want to refill a custom shape with new color or gradient I have to completely redraw its graphics, not just use a setFill method, right?
In easel there is no possibility to redraw just a container for example, so how can I manage to not update the whole stage, but just the one container that changed? I thought I can achieve this with caching, cache all containers the just update the one that changed, but this way didn't work at all for me.
Does it make sense to cache bitmap images? If there are custom shapes and images in a container what is better? Cache the container or just the shape in container.
I found a strange bug, or at least an interesting clue. My canvas layers totally overlapping. On the inferior layers the mouseover listening is working well, but the click isn't on the very same container/object.
How can I produce a click event propagation to overlapped layers those have click listeners? I've tried it with simple DOM, jquery, but the event objects were far away from what canvas listeners wanted to get.
In brief, methods and props I've already played with bare success when tried tuning: cache(), updateCache(), update(), mouseEnabled, snapToPixel, clear(), autoClear, enableMouseOver, useRAF, setFPS().
Any answer, suggestion, starting point appreciated.
UPDATE:
This free board game is a strategy game, so you are facing a world map, with ~30 territories. The custom shapes are the territories and a container holds a territory shape and the icons that should be over the territory. This container overlapping is minimal.
An example mouse event is a hover effect. The player navigate over the territory shape then the shape is getting recolored, resized, etc and a bubble showing up with details about the place.
Basically, maximum amount of 1-3 container could change at once (except the init phase -> all at this time). Not just the animations and recoloring slow in FF, but the listener delay is high too.
I wrote a change handler, so I only stage.update() up on tick the modified stages and the stages where an animation is running (tweenjs).
In my first approach I put every image to the container that could be needed at least once during the game, so I only set visible flags on images (not vectors).
Regarding caching:
There are some strange caching-issues, somehow the performance can drop with certain sizes of the caching rectangle: CreateJS / EaselJS Strange Performance with certain size shapes
(2) Depending on how often you call stage.update();
(3)
Each time the update method is called, the stage will tick any
descendants exposing a tick method (ex. BitmapAnimation) and render
its entire display list to the canvas. Any parameters passed to update
will be passed on to any onTick handlers.
=> Afaik it rerenders everything if not cached
(4) Yes.
(5) No. (I don't know of any)
(6) If the content's of the container don't change often, I'd cache the whole container, otherwise the container will be reconstructed every frame.
I have a question though: Why do you use multiple canvases? How many do you use? I could imagine that using multiple canvases might slow down the game.
How many sprites do you use in total?
2: if your layer or stage doesn't change, don't call stage.update() for that layer (so it doesn't gets rerendered, gives me a much lower cpu!)
For example, keep a global "stagechanged" variable and set this to true when something has changed:
createjs.Ticker.addEventListener("tick",
function() {
if (stagechanged)
{
stagechanged = false;
stage.update();
}
});
(or do you already use this, as stated in your "update"?)
4: I found a way to update for example the fill color :)
contaier1.shape1.graphics._fillInstructions[0].params[1] = '#FFFFFF';
(use chrome debugger to look at the _fillInstructions array to see which array position contains your color)
5: I found a way to just paint one container :)
//manual draw 1 component (!)
var a = stage.canvas.getContext("2d");
a.save();
container1.updateContext(a); //set position(x,y) on context
container1.draw(a);
a.restore();
I'm developing a rendering engine for a game i am currently building..
I have a main camera (rectangle) that determines what needs to be rendered (thing within it's boundaires)
I am using a bitmap rendering method for the background and that all works fine.
but for the character i am using a movieclip over the top.
when the character goes out of the camera's view is it 100% neccesary to set visible=false?
atm the game is running at 30 FPS (as intended) and everything is sweet, i just wanted to ask out of curiosity.
Is flash clever enough to not bother with movieclip outside of the scene boundaires?
Thanks in advance,
Rory
According to http://help.adobe.com/en_US/as3/dev/WS5b3ccc516d4fbf351e63e3d118a9b90204-7e3e.html Flash won't render if an object is outside of Stage boundaries:
Display list
The hierarchy of display objects that will be rendered as visible
screen content by Flash Player and AIR. The Stage is the root of the
display list, and all the display objects that are attached to the
Stage or one of its children form the display list (even if the object
isn’t actually rendered, for example if it’s outside the boundaries of
the Stage).
In my experience display objects added to the stage cause a performance hit even if they are not rendered.
Setting visible to false causes a much lower performance hit, but still a small hit.
Removing unnecessary display objects from the display list is a documented performance tip from adobe as well.
Of course, if you only have a few dislay objects it might not be worth the effort, but if we talk about large amounts of display objects I strongly recommend removing them from the display list.
How do I place objects that appear only if the background scrolls to a certain point?
Example- I have this long image that keeps scrolling using the technique above. However, after scrolling to part of the image, I want to add a platform there. How would I do that?
In general, you will probably need to save the locations of your objects in a file and then load that file at the beginning of the level (assuming you are making some kind of platformer game). You can do this by creating a class or a struct containing all the relevant information for the platform (position, size, texture, etc) and then using XML serialization to write an array of those classes/structs to a file.
Your level loader would then load and deserialize the level data, which would end up being a list of all the objects in your level (such as platforms). Now that you have the locations of your platforms in memory you have a couple different options on how to get them to the screen.
Draw all the objects (platforms) all the time, whether or not they are in the view of the camera. If your levels don't contain a lot of objects, this would be simple to implement.
Draw only those in the camera's view. Without knowing how you implemented the horizontal scroller, it's kind of hard to make suggestions for this part. Whatever mechanism you currently have to identify the boundaries of what part of the background to show could be used to determine which objects to draw as well.
I'm working on a game that scrolls vertically right now, and I needed a way to do something similar: place objects in a level and have them appear when the background scrolled to them. I used TorqueX 2D (free engine binaries if you've payed to develop for XNA) and its 2D scene editor to set this up pretty easily. I have my camera scrolling up, the background stays in place. When it gets to an object position defined in the XML level file it spawns the object in the level.