Hey guys, I'm trying to separate my image loading into a separate thread to show a nice loading screen (and perhaps be able to do some background loading at some point, whatevs). However, when I run it on my Mac (OSX Lion) I get a cryptic error:
WTF? I googled the error and it seems to be a mac error related to child processes and OSX Lion, but I tried running the code on my windows computer (Windows 7) and it spits out a completely white image. What the hell am I doing wrong?
function love.load()
image = nil
thread = love.thread.newThread("load", "load.lua")
thread:start()
thread:send("path", "image.png")
end
function love.draw()
if image then
love.graphics.draw(image, 0, 0)
end
end
function love.update(dt)
local receive = thread:receive("image")
local error = thread:receive("error")
if receive then
image = receive
elseif error then
print(error)
end
end
require "love.graphics"
require "love.image"
require "love.filesystem"
local thread = love.thread.getThread()
local path = nil
while path == nil do
path = thread:receive("path")
end
local image = love.graphics.newImage(path)
thread:send("image", image)
There's a warning on the wiki that you should not use the graphics module in threads. love.graphics.newImage tries to upload the image to the GPU, but only the main thread is allowed to do that. Use love.image.newImageData to load the data and pass that back to the main thread.
In 0.7.2 the image module has some threading problems. Don't access the functions or ImageDatas with multiple threads at the same time.
function love.load()
image = nil
thread = love.thread.newThread("load", "load.lua")
thread:start()
thread:send("path", "image.png")
end
function love.draw()
if image then
love.graphics.draw(image, 0, 0)
end
end
function love.update(dt)
local receive = thread:receive("image")
local error = thread:receive("error")
if receive then
image = love.graphics.newImage(receive)
elseif error then
print(error)
end
end
require "love.filesystem"
require "love.image"
local thread = love.thread.getThread()
local path = nil
while path == nil do
path = thread:receive("path")
end
local image = love.image.newImageData(path)
thread:send("image", image)
In my opinion, threads are so limited and temperamental that I'd suggest just using coroutines. Load one image (or sound or whatever) per frame (or per n frames, depending on how you want to affect your framerate). Not quite the same, but close enough, and with less hassle.
Earliest Love2D supporter who can't Love anymore. Let me disable pixel shaders if I don't use them, dammit! Lenovo Thinkpad X60 Tablet, built like a tank. But not fancy enough for Love2D 0.10.0+.
It's more or less the only way to load resources in a separate thread.
I mean, it's up to you how the thread knows what to load and when. Once you have the ImageData or Source you can pass their reference back and forth between threads wherever it's needed.
I have some experience with images in threads, but don't know about audio. Perhaps someone else knows if there's some catch.
I am looking forward to alternatives that would allow us to do more with threads, 0.10.0 has been mentioned as complete-backend-overhaul-release-time-thingy-at-this-point-Im-just-making-the-word-longer.
out of interest, what images are you loading that are taking long enough to need a loading screen? Ive only really had lag on startup when actually generating a large image and populating it with mapPixel/setPixel