What’s the current status of this topic? I’ve read through a few different threads and tried a few different things, but couldn’t really get anything working (but maybe I was just sleep-deprived).
Here’s what I want to do:
Dynamically load images at runtime.
Display them in world space, attached to game objects.
They will be in an arbitrary place on my hard drive. I will have the full, absolute path.
There could be a few dozen of them at least.
They will have wildly varying sizes, from tiny sprites to full-screen backgrounds.
Is this currently possible?
I tried Sergey Lerg’s ImageLoader extension, it loads all my images like a champ, but I’m not quite sure what to do after that. If I get “texture0” on a sprite and use resource.set_texture, that turns ALL my sprites into white squares. Which I guess is because I’m changing the texture of the whole atlas, and the UVs are all wrong? sys.load_resource() only works on bundled files, so that’s no good. I tried using GUI nodes with image.load() and gui.new_texture(), but so far I just get “WARNING:GUI: Failed to create dynamic gui texture (-6)”. And I guess GUI components won’t inherit position from game objects, so I would have to manually update their positions every frame, which isn’t ideal.
I’m not really concerned about performance—batching, etc.—and I won’t be loading gigabytes of images or anything, I just want it to work.
I also have issues with dynamic image loading. When I read an image the alpha gets all messed up. The middle here is the one with messed up Alpha. I tried opening it in Photoshop and that works as it should.
This is how I load it.
local file = io.open(image_path, "rb")
if not file then
return
end
local buffer = file:read("*all")
file:close()
local img = image.load(buffer)
gui.new_texture("icon" .. name , img.width, img.height, img.type, img.buffer, false)
I have a bunch of gameobjects with quad models attached to them. Each model has a single texture of 1x1 white png. For each gameobject a separate png file. So img_1.png, img_2.png … img_40.png. For as many images you want to be able to show simultaneously on the screen.
Then I load different files into different gameobjects and they show up ok.
All that I try to load like this, in the example the image is 8bit. I have also tried 16 bit. The images are in RGB mode. Going to see if the ImageLoader extension would help.
function init(self)
local f = assert(io.open("poke.png", "rb"))
local data = assert(f:read("*a"))
local img = image.load(data, true)
local type = (img.type == image.TYPE_RGB) and "rgb" or "rgba"
gui.new_texture("pokemon", img.width, img.height, type, img.buffer, false)
gui.set_texture(gui.get_node("box"), "pokemon")
end
Note the true for premultiplication of alpha: image.load(data, true)
@sergey.lerg Thanks for the tip, that works! Whew, finally! It’s really really annoying to have to set up, say, 40 images, 40 game object files with models using those images, and 40 factories to spawn those objects…but I guess that’s what I have to do.
If it’s “only” 40 or so, it’s probably just as fast to do it by hand, but then if I ever need more…*sigh* Yeah I should probably do that.
Things like this are what make me hop the fence back to Love2D, where instead of the several hours of frustration I’ve spent on this, I just write two lines of code:
local image = love.graphics.newImage(filepath)
love.graphics.draw(image)
…but now I’m just whining. I know in 99% of cases, Defold’s optimizations are awesome, and don’t limit you at all.