Jump to content

Exception when using transferTextureToImage


photo

Recommended Posts

Hello,

I am currently updating a code from SDK 2.16 to SDK 2.18.1.

According to the SDK 2.17 migrations updates, this piece of code in 2.16 : 

// save texture to file
ImagePtr image = Image::create();
texture->getImage(image);
image->save(file_name);

// apply texture to disk mesh
if (object_dst->getNumSurfaces()>0)
	object_dst->setMaterialTexture(material_texture_name.get(), file_name.get(), 0);

would be updated to :

// save texture to file
ImagePtr image = Image::create();
// synchronous 
Render::transferTextureToImage( 
	MakeCallback([&](ImagePtr image) 
		{
			image->save(file_name);
		}),
	texture);

// apply texture to disk mesh
if (object_dst->getNumSurfaces()>0)
	object_dst->setMaterialTexture(material_texture_name.get(), file_name.get(), 0);

The code was working in 2.16 and now it is raising an exception in 2.18 (access violation exception) when the callback tries to read the variable file_name (this variable scope is the function where the callback is created).

Is it normal ? if yes how should I change that code to make is work ?

Best regards.

Link to comment

Hello!

On 6/28/2024 at 10:03 PM, AntoineAB said:

The code was working in 2.16 and now it is raising an exception in 2.18 (access violation exception) when the callback tries to read the variable file_name (this variable scope is the function where the callback is created).

Is it normal ? if yes how should I change that code to make is work ?

You don't need to create an image variable because transferTextureToImage does it automatically and deletes it after the callback. Also, transferTextureToImage will be called with the swap at the end of this frame. So, if you need to save the image and then set the texture by path you should do it inside the callback.

Otherwise, you can set the texture itself not by path. To do this you should get the material and use setTexture. For example:

object_dst->getMaterial(0)->setTexture("name", texture);

Thanks!

Link to comment

Hello,

Thank you for the information.

But I still have the problem. I can't use local variables in the callback because they seem to be destroyed when the callback is called.

Here is another example :

void takeScreenshot::init()
{
  std::stringstream stringStreamPath;
  stringStreamPath << GetImagesFolderPath();

  // synchronous 
  Render::transferTextureToImage( 
      MakeCallback([&](ImagePtr image) 
          {
              image->save(file_name);

              std::string filename = stringStreamPath.str();
              image->save(filename.c_str());
              Log::message("Screenshot saved to %s\n", filename.c_str());
          }),
      texture);
}

Here, the problem is that the callback returns an exception (access violation exception) when it tries to read stringStreamPath.

How could I use a variable in a callback that is created outside of a callback ? or is it the wrong way to do it ?

Regards.

Link to comment

You have declared the variable in the local scope (within the takeScreenshot::init function scope) so when the scope exits all local variables will be freed. Therefore, you need to declare stringStreamPath outside of the local scope (for instance in the takeScreenshot class) and then pass it as you already do; it shouldn't be destroyed.

Additionally, don't assume that transferTextureToImage will call the callback immediately because it called "synchronous" because actually it will be called later in this frame. That's why your scope exits and local variables are cleared.

Thanks!

Link to comment
×
×
  • Create New...