OTHGMars Posted April 19, 2018 Share Posted April 19, 2018 How do you update part of a texture and leave the rest intact? I have a texture: GFXTexHandle mTexture; mTexture.set(1024, 768, GFXFormatR8G8B8A8_SRGB, &GFXDynamicTextureSRGBProfile, "", 1, 0); This code will paint the entire texture blue: GFXLockedRect *rect = mTexture.lock(); for (U32 y = 0; y < 768; ++y) for (U32 x = 0; x < 1024; ++x) { // Paint entire texture blue(d3d) or red(ogl) U32 idx = (y * rect->pitch) + (x * 4); rect->bits[idx] = rect->bits[idx + 1] = 0; rect->bits[idx + 2] = rect->bits[idx + 3] = 255; } mTexture.unlock(); If I try to update part of it with: RectI updateRect(0, 0, 256, 256); GFXLockedRect *rect = mTexture.lock(0, &updateRect); for (U32 y = 0; y < 256; ++y) for (U32 x = 0; x < 256; ++x) { // Paint (0,0,256,256) red(d3d) or blue(ogl) U32 idx = (y * rect->pitch) + (x * 4); rect->bits[idx + 1] = rect->bits[idx + 2] = 0; rect->bits[idx] = rect->bits[idx + 3] = 255; } mTexture.unlock(); I end up with a texture where the top left 256x256 square is red, but every other pixel in the texture has been set to (0, 0, 0, 0). It doesn't seem to matter if I lock just the update RectI, or lock the entire texture, I get the same result. That's with d3d11. If I switch to open gl, I get my desired result of the left top 256x256 blue and the rest red. I did some digging in the lock function https://github.com/GarageGames/Torque3D/blob/development/Engine/source/gfx/D3D11/gfxD3D11TextureObject.cpp#L100-L116. First thing I notice is RectI r; is assigned and never referenced (but that's semi-irrelevant). D3D11_MAP_WRITE_DISCARD led me to this: https://stackoverflow.com/questions/23368880/differences-of-directx11-d3d11-map which describes my problem exactly, but D3D11_MAP_WRITE_NO_OVERWRITE throws a runtime error.OpenGL:https://github.com/GarageGames/Torque3D/blob/development/Engine/source/gfx/gl/gfxGLTextureObject.cpp#L76-L91 A separate memory rectangle is actually created with an updated pitch value. The indexing into the GFXLockedRect is different than it is for d3d where the pointer is always to the pixel at 0,0, but the locked pixels can be updated and the remaining pixels are unchanged. I also found with openGL, I can lock the entire texture, only update some pixels and the rest retain their previous value.Is there any way to update part of a GFXDynamicTextureSRGBProfile texture in d3d11 without needing to copy the entire texture? Quote Link to comment Share on other sites More sharing options...
Timmy Posted April 19, 2018 Share Posted April 19, 2018 Yes this is d3d11 bug, i will fix this when i get some time over the weekend and submit a PR for it. Quote Link to comment Share on other sites More sharing options...
OTHGMars Posted April 19, 2018 Author Share Posted April 19, 2018 Awesome, Thanks Timmy. Quote Link to comment Share on other sites More sharing options...
Timmy Posted April 23, 2018 Share Posted April 23, 2018 if there is anyone else that has come across this bug i have submitted a PR for this here Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.