Imageloader seems to interfere with dynamically loading gui textures

Hello there,

I have a game collection that houses all my models.
This collection also contains a gui slideshow that is enabled/disabled as needed.

I dynamically load the textures for the models with the imageloader extension by @sergey.lerg.
The slideshow uses the built-in sys.load_resource method since I don’t know how to implement imageloader for gui nodes.

When I use the two methods together, the images in my gui slideshow are mirrored along the x-axis unless I disable the function that loads the model textures with imageloader.

I could of course rotate the gui node but I am curious if I might be doing sth wrong here.

This is the code I use:
loading the models with imageloader in the game.script:

local function set_model_textures()	
	local paintings_count = 86
	for i = 1, paintings_count do
		local data = sys.load_resource("/assets/uvs/"..i..".jpg")
		local image_resource = imageloader.load({ data = data })
		local texture_address = go.get("/models_paintings#painting"..i, "texture0")
		resource.set_texture(texture_address, image_resource.header, image_resource.buffer)
	end	
end

And loading the images for the gui slideshow with the built-in method:

local function set_slideshow_textures()
	-- load the image
	local loadimage = sys.load_resource("/assets/uvs/"..imagenumber..".jpg")
	local img = image.load(loadimage)
	gui.new_texture("image"..imagenumber, img.width, img.height, img.type, img.buffer, false)
	gui.set_texture(imagebox, "image"..imagenumber)
end

Example:

I think that several image formats have their pixels ordered such that the first pixel of the data is top-left (perhaps to mimic the scan lines of an old CRT)?

I flip pixel data vertically in my PNG extension:

And Sergey has a similar option:

1 Like

Thank you @britzl!
There no problem with mirroring with either method. Just when both are used at once, the gui textures are affected - textures for which I don’t use imageloader. Imageloader is for go textures, not for gui textures - or might I be wrong there? In any case, I don’t understand as to why using imageloader for my models would lead to mirroring when I load my gui textures - with another method and in another script. :thinking: It’s no big deal, I’ll just rotate the node, but I am really curious to understand what is happening here.

Are they sharing the same texture perhaps?

1 Like

Yes, they do, the use the same images from the custom resources.
I’ve just rotated the gui box by 180 degrees and all is good - which is bit weird in itself, since it should not get rid of the mirroring, but it does.
the mirrored image:


rotating it by 180 degrees should lead to this:

but I do get this, the correct image:

Well, I don’t mind, as long as it works :smiley:

2 Likes

There is a setting “no_vertical_flip = true” in the image loader API. Try it.

2 Likes

Hello Sergey!

Thank you, I’ll have a look and see how to do this.
While you are here: I am right that your extension cannot be used for gui nodes?

It can but not directly, you have to perform costly conversions for loading into gui. There was an example somewhere…

1 Like

Thank you.

Costly, that doesn’t sound good :grinning_face_with_smiling_eyes:

I did search, must have missed it.

Should the line look like this?

local image_resource = imageloader.load({ data = data, no_vertical_flip = true })

If so, my gui images are still mirrored.

Yeah, try no_async = true as well. If that doesn’t help sadly I don’t know what’s going on.

1 Like

No, sadly, didn’t work either.
But no worries, the rotation of the gui box is a working solution.
Thank you very much for your help!

And don’t forget to put local everywhere you can, otherwise you’ll end up with weird bugs.
local loadimage, local img

2 Likes

I just noticed. I defined the variables concerned as local ones at the top of the script. Should have altered the lines before posting. Fixed the post right now.

I made a little test project and can confirm that the image loader extension interferes with the built-in GUI image loading. They don’t even have to be the same images, if you load any image with the extension, any textures loaded after that with image.load and gui.new_texture will be flipped.

img-load-test.zip (36.0 KB)

screenshot_2022-08-11_10-50-38

If you comment out loading the image with the extension, then the GUI texture loads correctly:
screenshot_2022-08-11_10-50-49

If you pass in “no_vertical_flip = true” to the image loader, then it simply flips both.
screenshot_2022-08-11_10-52-58

If you use “info = true” to only load the header info, then the GUI loading still works fine, no flipping.

3 Likes

Only thing I can think of is that his extension uses the same library as we do.
Perhaps they collide somehow.
Also, his version of stb_image.h is 2.19, whereas ours is version 2.26.

3 Likes

The extension uses stb_image implementation from Defold. There is stb_image.h in the extension solely because Defold was closed source back then.
What should be the correct include path for the stb_image.h file? So I can remove it from the extension.

1 Like

It is not public and I don’t think we will make it public since we may want to change it later on.
We could possibly rename the symbols.
It is more likely we’ll expose our image loading functions.

However, I still think there should have been symbol clashes, so I guess we have already renamed our internal symbols.

I’ve updated the extension, updated stb_image.h and added a new debug function

imageloader.debug_set_vertical_flip(true | false)

You can use it to reset the vertical flip flag inside stb_image lib. Hopefully that should fix the issue. A better solution would have been remembering the flag and restoring it inside the extension but there is no API for that in the lib.

6 Likes

Hello Sergey,

thank you very much for updating the extension!

I played with Ross’ example project, I just replaced one of his lines to make the goings-on clearer:

local M = {}

function M.loadToGo(imagePath, component, flip)
	local data = sys.load_resource(imagePath)
	-- local image_resource = imageloader.load({ data = data, no_vertical_flip = flip })
	local image_resource = imageloader.load({ data = data, no_vertical_flip = false })
	imageloader.debug_set_vertical_flip(false)
	local texture_address = go.get(component, "texture0")	
	resource.set_texture(texture_address, image_resource.header, image_resource.buffer)
end

function M.loadToGui(imagePath, node, texID)
	local loadimage = sys.load_resource(imagePath)
	local img = image.load(loadimage)
	gui.new_texture(texID, img.width, img.height, img.type, img.buffer, false)
	gui.set_texture(node, texID)
end

Outcome:
Screenshot 2022-08-12 at 09.19.07

So, this needs to be done to avoid the flipping of the gui image:
Set “no_vertical_flip” to false:

local image_resource = imageloader.load({ data = data, no_vertical_flip = false })

and in the next line reset the flag with your new debug function, again to false:

imageloader.debug_set_vertical_flip(false)

Using “true” in both lines has this outcome.
Screenshot 2022-08-12 at 09.28.54

So, problem solved, great, thank you, Sergey!

5 Likes

Found a new problem:

when using the new debug function, the loading fails on html, the screen stays black:

Screenshot 2022-08-12 at 12.15.02

Same on Android but strangely no warnings in logcat.

The app runs fine when the debug function is commented out.

1 Like