lock() changes texture color?

If you are a new Irrlicht Engine user, and have a newbie-question, this is the forum for you. You may also post general programming questions here.
Post Reply
LunaRebirth
Posts: 386
Joined: Sun May 11, 2014 12:13 am

lock() changes texture color?

Post by LunaRebirth »

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.
Image

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.
CuteAlien
Admin
Posts: 9645
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: lock() changes texture color?

Post by CuteAlien »

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).
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
LunaRebirth
Posts: 386
Joined: Sun May 11, 2014 12:13 am

Re: lock() changes texture color?

Post by LunaRebirth »

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.
Post Reply