Jump to content

Updating a dynamic texture?


OTHGMars

Recommended Posts

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?

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...