0 votes

I am working on integrating my SSTT AR tracking engine into Godot for later release as free plugin. However I need to pick the brain of the community regarding texture upload from an external image.

I tried pulling and pushing textures / images. Here are the two methods I tried:

Method One: in GDNative I created a godot_pool_byte_array to keep the image data, hand this over with a variant and set it in an image which is attached to a Texture. It works but it leaks like crazy because set_image (in ImageTexture) or set_data (in Image) seem to create a new image every call. One can see this in the remote debugger as on every call a new instance of an image is being attached to the ImageTexture.

Method Two: in GDNative I have a function where I planned to copy the image data (capture data) into the byte buffer. The copy is done (I check the pointer its always the same). But again here the texture is not being update. I fenced the write to the GDScript handed in PoolByteArray into a godot_pool_byte_array_write_access which returns a nullpointer on godot_pool_byte_array_write_access_ptr. So no luck with this path either.

So, any other possibilities?

in Engine by (24 points)
edited by

Assigning new data to an Image should not create an additional image, there is probably a bug there...
Also when you say "leak", you mean memory goes up until starved?

ImageTexture is creating a new Image every time a new (even the same) PoolByteArray is being set to the attached Image. This does not leak - I didn't have a deeper look with valgrind.

What leaks is when you are using get_data() on the Image try to hand it over to a conversion (in my case a camera capture module) method and try to set it back. As reduz pointed out the API design is taking a immutable approach on the PoolXArray stuff.

I think there needs to be much more documentation around those kind of things. I only figured it out by trial and error, well and reading bug reports.

1 Answer

0 votes

For reference as other people will likely try to do some GDNative stuff, here is my approach:

Within GDNative module I am keeping a PoolByteArray instance. If I get the first frame I instantiate a new PoolByteArray with
api->godot_pool_byte_array_new(&user_data->pba); api->godot_pool_byte_array_resize(&user_data->pba,img_size);
if the user changes camera settings or the you need to destroy the image and re-instantiate.

to use the data just get a variant with the PoolByteArray

api->godot_variant_new_pool_byte_array(&ret,&user_data->pba);

on the GDScript part this translates to

 var data = gdni.get_data()

nodeImage.data.data = data

nodeImageTexture.set_data(nodeImage)

Hope this clears up some of the confusion.

by (24 points)
Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to webmaster@godotengine.org with your username.