Aeva / m.grl

Midnight Graphics & Recreation Library
http://mgrl.midnightsisters.org
GNU Lesser General Public License v3.0
44 stars 3 forks source link

Assigning generated content to textures #212

Open wijnen opened 8 years ago

wijnen commented 8 years ago

In order to assign a new value to a texture, an element (in particular, a 2-D canvas) can be inserted into the media storage and used:

please.media.assets['id'] = canvas;
node.shader.diffuse_texture = 'id';

However, when this is repeated, the storage cache is not updated, but instead the original version is used. This is usually a good thing, but not when the object has changed, which may be the reason for using this method with generated content.

Aeva commented 8 years ago

I have two thoughts about how to automate the uploading, and a third for how to make the api cleaner.

First would be that the canvas object could be tagged with a property "dirty", which when set to true, indicates that the texture should be re-uploaded on the next frame, at which point it would be set back to false again.

Second version would be tagging the canvas as "animated", which indicates that the texture should always be re-uploaded every frame, and this would never be automatically set back to false.

As for an api, I think we could add something like please.sideload(uri, element); for elements like canvas, at it would mix-in all of the special properties as well as allowing instancing like we do with images.

Thoughts?

wijnen commented 8 years ago

The dirty property sounds useful for things that don't change a lot. For animated, I like it, but in addition I would like to have a callback, to avoid redrawing the canvas when nothing is being displayed. Another way to do this would be to have this callback, which must set dirty if it actually redraws the canvas. Then it can also limit the load by lowering the framerate. This is probably already possible (except for dirty not existing), but I think it would be good to have access to it from the node object (as opposed to the pipeline machinery).

As for the API, what would uri be in that call? Would the jta just reference a texture image, but this forces a canvas into the cache which will be used instead of that file? So this command would need to be given before loading the jta file? I think that would work.

wijnen commented 8 years ago

I think node.before_render is the callback I'm looking for, which is fine. So I think just dirty would be enough, and animated shouldn't be needed.

Aeva commented 8 years ago

(as we mentioned in a conversation elsewhere) the before_render callback is only on render_nodes.

The uri would just be whatever you want to call the asset, so you could do something like

please.sideload("my_animated_canvas", canvas_el);
some_character.shader.diffuse_texture = "my_animated_canvas";

Having a dirty flag on the canvas would be handy in that you could just flag it every time you update the canvas, and m.grl would know to re-upload it. Having an always_dirty flag (or, 'animated') and a limiting framerate would be handy if it is assumed the canvas is just going to be frequently updated. Personally, I think the dirty flag is a better idea though.

The ideal case would be if canvas elements had an "on changed" event, and then m.grl could just hook into that, but it seems like such a thing doesn't exist :/ I think the dirty flag alone is probably enough for canvas, but I'm wondering now if the things like the 'video' element would need m.grl to manually reupload or if the browser does that automatically >_>