How to get Texture from Assets in Lime environment?

I’d like to get instance of flash.display3D.textures.Texture in order to upload it to the Context3D. Lime asset manager suggests me just Assets.getImage() method that returns the incompatible lime.graphics.Image instance.
So, how to get flash.display.BitmapData or something else to apply in to the Texture instance or may be directly upload to Context3D by uploadFromBitmapData() or may be uploadFromByteArray() methods?
OpenFL suggests wrapped BitmapData by Assets.getBitmapData() method, but Lime does not :frowning:

You should be able to use openfl.Assets to get a BitmapData instance, it wraps lime.Assets

You can also use (if I remember correctly) BitmapData.fromImage () to create a BitmapData instance from a Lime Image

Also, on a Flash environment, image.src should be a BitmapData, that’s probably what you want :slight_smile:

Call

var image:Image = Assets.getImage("assets/ground.jpg");

causes an error [Fault] exception, information=ArgumentError: Error #2015: Invalid BitmapData. in string

@:keep @:bind #if display private #end class __ASSET__assets_ground_jpg extends flash.display.BitmapData { public function new () { super (0, 0, true, 0); } }

of the DefaultAssetLibrary class. I suppose it’s because of zero bitmap sizes in constructor.
Have I request Image asynchronously by loadImage() method? I have checked compiled SWF – it contains embedded __ASSET__assets_ground_jpg class at the second frame.

Oh, if you call this during create() or init() the preloader has probably not finished yet, exec() is called after the assets are all preloaded and it’s time to run the application

Thanks, everything works fine now. But I’m still surprised by the sequence and signatures of method calls:

  • Application::init(aContext:RenderContext) – to init rendering context while assets are still not ready, so I just select current rendering context because I can’t upload at this step textures to the GPU;
  • Application::exec() – now textures are ready, but context have been set one step earlier, from there I at last setting up hardware, uploading textures and so on;
  • Application::render(aContext:RenderContext) – there is no sense in passing render context, it can’t be changed in runtime anyway, so there I ignore argument and render frame, based on current timestamp;

init was called after assets were loaded in the beginning of the API, but I realized that there were problems where you were not able to control the process soon enough

Theoretically, the context type could change (for example, multiple windows with different context types) and I want to encourage code that isn’t locked always to only one renderer type but I’m still debating this all – open to ideas.

Perhaps create could occur before preloading (but late enough for the control needed in init) and init could occur after preloading (to make it more practical), perhaps init should not pass the renderer context (but application.renderer should be defined?) or I even wonder if render should pass a renderer instance (or nothing at all?) to better support multiple windows (so you can check renderer.window)

@meps Oh, now I remember :smile:

Calling init after preload was nice, but then we had the problem of not having a render context to draw something while we wait for preload to complete. As a result, we need to be set up to draw, even before we have all our assets. Perhaps there’s some good way we could hook into when preload is complete, or we could drop init as a render related method, and do something else, such as immediately within create or something

I’m open, I know some of this life-cycle stuff just need to be polished a little :slight_smile:

May be just rename exec to ready and remove disguising context argument from render?
I’m still thinking that render context can’t change on one platform. How does it will look like – we started application in windows environment then open flash player and got stage or may be browser window and got webgl? If it is really possible then we should listen for one root factory and get new objects for every created context and walk through all init-ready-render steps.

The exec method is actually the main loop on most platforms:

var result = app.exec ();
Sys.exit (result);

Application exec exits when the application is done running. This is why we get the “on ready” timing from exec, but ultimately it’s the wrong method to feel nice here :smile:

Perhaps an onPreloadComplete or other (similar) event would help here, and perhaps init should be onRenderInit or something like that that’s less generic.

In this way, you can handle when the renderer is ready, but also know when preloading is done and assets are prepared. In fact, we should also have hooks for preloader progress.

I think a big concept with render is that multiple windows will each call render, so (in the future) an application with three windows will call render three times, one for each context, but you’re right – for the lifetime of a renderer, I think it should stay one type.

OpenFL will mix-and-match renderer types as desired (like GL + Cairo or Canvas + DOM) but this doesn’t happen at the Lime level, the Lime renderer stays as the same parent context type

I just made some changes in Lime to help improve the handling of preloading.

onPreloadProgress and onPreloadComplete now dispatch on the Application class, so you can handle preloader progress updates or the complete event.

I also added application.preloader, so you can check preloader.complete in your Application instance, too, if you want. I updated the “SimpleImage” sample to use this

It’s more clear without init() method now.

I hope the Lime 2.6 API feels a bit better, please let me know if anything else feels rough. In the repository, I have another change that I’m thinking will help with the renderer type, you can switch (renderer.context), but also be able to if (renderer.type == OPENGL) to do a simple if instead of a switch :slight_smile: