I have been trying to find the source of this issue for the last few days, and I am stumped.
I tried reproducing the problem in a new Irrlicht project, but it just doesn't happen, so I was wondering if anyone else has come across this issue before.
When I call lock() to grab an image's pixels from a texture, the image and all textures using the image become slightly more dark.
This happens when I copy from one image to another.
In the image below, I am trying to use IImage->copyTo() to copy a tile from the editor onto the world.
Each time that I select the ground to copyTo(), this weird thing happens.
Does anyone have any ideas or have seen this before??
I'm stumped
The weird thing is that if I never call unlock(), the image only becomes slightly dark once and never more dark again.
But if I lock(), unlock(), lock(), … repeatedly, it will get dark enough to be black.
lock() changes texture color?
Re: lock() changes texture color?
Sounds like alpha gets multiplied each time. I had a similar problem with D3D when we changed lock() code from keeping copy on CPU side to getting the image from GPU each time. That's why I switched it back for that - but maybe GL ES driver also works like that (all drivers should work like that - aside from this problem). Basically - you got RGBA on CPU and then the end-result on GPU is RGB multiplied by alpha. But the alpha value is kept unchanged. When you lock() - unlock() it results it multiplying the alpha value again to RGB.
Unfortunately I'm still not yet deep enough in driver programming to know how to work around this (aside from keeping an image copy on CPU side). One can remove the alpha after lock() - but then it's simply lost completely which is generally also not what you want. Probably the solution would be to not apply alpha at all in this step and just do that later in shaders or something like that - I don't know... (not even yet how to tell drivers not to apply alpha).
Unfortunately I'm still not yet deep enough in driver programming to know how to work around this (aside from keeping an image copy on CPU side). One can remove the alpha after lock() - but then it's simply lost completely which is generally also not what you want. Probably the solution would be to not apply alpha at all in this step and just do that later in shaders or something like that - I don't know... (not even yet how to tell drivers not to apply alpha).
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
-
- Posts: 386
- Joined: Sun May 11, 2014 12:13 am
Re: lock() changes texture color?
Hmm yeah I'm not sure.
I tried a BMP image, which shouldn't support alpha, but ->getColorFormat() still returns A8R8G8B8. Maybe it does this by default, I'm not well-versed in the graphics side of things.
I tried setting the color format from A8R8G8B8 to R8G8B8 while copying from images, but then the image looks really funky, almost like it's corrupted, and the darkness still applies.
Storing the pixels from lock() into a variable, using that during createImageFromData(), and then never unlock()ing seems to fix the issue, though I really don't want to have to do that.
One more thing: passing video::ETLM_READ_ONLY into lock() before unlock()ing will also only make the texture darker once, but never darker again.
I tried a BMP image, which shouldn't support alpha, but ->getColorFormat() still returns A8R8G8B8. Maybe it does this by default, I'm not well-versed in the graphics side of things.
I tried setting the color format from A8R8G8B8 to R8G8B8 while copying from images, but then the image looks really funky, almost like it's corrupted, and the darkness still applies.
Storing the pixels from lock() into a variable, using that during createImageFromData(), and then never unlock()ing seems to fix the issue, though I really don't want to have to do that.
One more thing: passing video::ETLM_READ_ONLY into lock() before unlock()ing will also only make the texture darker once, but never darker again.