   Copy Texture
  Hello I am trying to copy/clone a texture but I get an error with my code. Is this not the right way to do it?IDirect3DTexture9 *textureCopy;*textureCopy = *mTexture; //mTexture is a LPDIRECT3DTEXTURE9Thanks.   
Quote:Original post by AntonymHello I am trying to copy/clone a texture but I get an error with my code. Is this not the right way to do it?*** Source Snippet Removed ***Thanks.Nope, that's not correct. Your choices are:D3DXLoadSurfaceFromSurface()LockRect() both surfaces and copy the bitsIDirect3DDevice9::StretchRect()IDirect3DDevice9::UpdateSurface()Each of those operate on surfaces, so you'll have to do each one for each surface level in the texture.However, this isn't usually something you'd want to do (Which is why there's no Duplicate() function or anything). Why do you need two copies of the same texture?;  Because if I have two or more objects that use the same texture and I edit one I don't want the other(s) to exhibit the edition too :S.   ;Quote:Original post by AntonymBecause if I have two or more objects that use the same texture and I edit one I don't want the other(s) to exhibit the edition too :S.Ok, that's fair enough (What you're trying to do is commonly called Copy On Write, or COW).What memory pool are your textures in? Assuming they're in D3DPOOL_MANAGED (They should be unless they're dynamic really), D3DPOOL_SYSTEMMEM or D3DPOOL_SCRATCH, you'd be best using the LockRect() method.Untested code:DWORD GetBytesPerPixelFromFormat(D3DFORMAT fmt){   switch(fmt)   {   case D3DFMT_R8G8B8: return 3;   case D3DFMT_A8R8G8B8:   case D3DFMT_X8R8G8B8:   case D3DFMT_A2B10G10R10:   case D3DFMT_A8B8G8R8:   case D3DFMT_X8B8G8R8:   case D3DFMT_G16R16:   case D3DFMT_A2R10G10B10:   case D3DFMT_X8L8V8U8:   case D3DFMT_Q8W8V8U8:   case D3DFMT_V16U16:   case D3DFMT_A2W10V10U10:   case D3DFMT_G16R16F:   case D3DFMT_R32F: return 4;   case D3DFMT_R5G6B5:   case D3DFMT_X1R5G5B5:   case D3DFMT_A1R5G5B5:   case D3DFMT_A4R4G4B4:   case D3DFMT_A8R3G3B2:   case D3DFMT_X4R4G4B4:   case D3DFMT_A8P8:   case D3DFMT_A8L8:   case D3DFMT_V8U8:   case D3DFMT_L6V5U5:   case D3DFMT_L16:   case D3DFMT_R16F:   case D3DFMT_CxV8U8: return 2;   case D3DFMT_R3G3B2:   case D3DFMT_A8:   case D3DFMT_P8:   case D3DFMT_L8:   case D3DFMT_A4L4: return 1;   case D3DFMT_A16B16G16R16:   case D3DFMT_Q16W16V16U16:   case D3DFMT_A16B16G16R16F:   case D3DFMT_G32R32F: return 8;   case D3DFMT_A32B32G32R32F: return 16;   }   // Unknown format   return 0;}LPDIRECT3DTEXTURE9 DuplicateTexture(LPDIRECT3DTEXTURE9 pSrc, LPDIRECT3DDEVICE9 pDevice){   // Get number of mip levels and size of top level   D3DSURFACE_DESC desc;   DWORD dwLevels = pSrc->GetLevelCount();   HRESULT hResult = pSrc->GetLevelDesc(0, &desc);   if(FAILED(hResult)) return NULL;   DWORD dwBytesPerPixel = GetBytesPerPixelFromFormat(desc.Format);   if(dwBytesPerPixel == 0) return NULL;   // Create a texture that is the same size   LPDIRECT3DTEXTURE9 pDest = NULL;   hResult = pDevice->CreateTexture(desc.Width, desc.Height, dwLevels, desc.Usage, desc.Format, desc.Pool, &pDest, NULL);   if(FAILED(hResult)) return NULL;   // Lock and copy each surface level in turn   for(DWORD i=0; i<dwLevels; ++i)   { // Lock source texture D3DLOCKED_RECT rectSrc, rectDest; hResult = pSrc->LockRect(i, &rectSrc, NULL, D3DLOCK_READONLY); if(FAILED(hResult)) {    pDest->Release();    return NULL; } // Lock destination texture D3DLOCKED_RECT rectDest; hResult = pDest->LockRect(i, &rectDest, NULL, 0); if(FAILED(hResult)) {    pSrc->UnlockRect(i);    pDest->Release();    return NULL; } // If the pitch is the same as bytes per pixel * width, then we can copy the // entire surface in one go. Otherwise, there's reserved data at the end of // each scanline, and we have to copy a row at a time. if(rectSrc.Pitch == desc.Width*dwBytesPerPixel && rectSrc.Pitch == rectDest.Pitch) {    memcpy(rectDest.pBits, rectSrc.pBits, rectSrc.Pitch*desc.Height); } else {    DWORD dwBytes = desc.Width*dwBytesPerPixel;    for(UINT y=0; y<desc.Height; ++y)    {  BYTE* pBitsSrc = (BYTE*)rectSrc.pBits + rectSrc.Pitch*y;  BYTE* pBitsDest = (BYTE*)rectDest.pBits + rectDest.Pitch*y;  memcpy(pBitsDest, pBitsSrc, dwBytes);    } } // Copy complete, unlock surfaces pDest->UnlockRect(i); pSrc->UnlockRect(i);   }   // All levels copied, return newly copied texture   return pDest;}Hmm, that took longer to write than I thought...EDIT: Removed dwLockFlags stuff, that's only valid for default pool textures, which aren't lockable anyway...[Edited by - Evil Steve on May 25, 2009 8:49:10 AM];  If you want them to use the same texture, just keep a pointer to the same texture ("textureCopy = mTexture").   ;  Wow that was fast. Thanks a lot!Edit: the hResult fails for some reason :S.  // Lock destination texture hResult = pSrc->LockRect(i, &rectDest, NULL, 0); if(FAILED(hResult)) {    pSrc->UnlockRect(i);    pDest->Release();    return NULL; }This is the code I use to load a texture.Sprite* Direct3D::LoadSprite(LPCTSTR fileName,  float textureWidth,  float textureHeight,  float mFrameWidth,  float mFrameHeight){LPDIRECT3DTEXTURE9 texture;D3DXCreateTextureFromFileEx(d3d_device, fileName, D3DX_DEFAULT_NONPOW2, D3DX_DEFAULT_NONPOW2,D3DX_DEFAULT, 0, //D3DUSAGE_RENDERTARGET? //0D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, //DEFAULT? //MANAGEDD3DX_DEFAULT, D3DX_DEFAULT, D3DCOLOR_XRGB(255, 0, 255),NULL, NULL, &texture);Sprite *sprite = new Sprite(texture, textureWidth, textureHeight,mFrameWidth, mFrameHeight);return sprite;};Quote:Original post by AntonymWow that was fast. Thanks a lot!Edit: the hResult fails for some reason :S.What do the Debug Runtimes say the problem is?Also, that was a typo which I corrected; it should be:hResult = pDest->Lock(...EDIT: In fact, that's probably the problem - you can't have two locks on one surface (Or they can't be overlapping regions, I don't recall offhand)   ;  Yeah that was the problem though another one popped up. The problem occurs at.    DWORD dwBytes = desc.Width*dwBytesPerPixel;    for(UINT y=0; y<desc.Height; ++y)    {  BYTE* pBitsSrc = (BYTE*)rectSrc.pBits + rectSrc.Pitch*y;  BYTE* pBitsDest = (BYTE*)rectDest.pBits + rectDest.Pitch*y;  memcpy(pBitsDest, pBitsSrc, dwBytes);    }The debugger tells me.Direct3D9: :DoneExclusiveMode'Dungeon.exe': Loaded 'C:\WINDOWS\system32\usp10.dll'First-chance exception at 0x1023fe24 (msvcr90d.dll) in Dungeon.exe: 0xC0000005: Access violation writing location 0x01899000.Unhandled exception at 0x1023fe24 (msvcr90d.dll) in Dungeon.exe: 0xC0000005: Access violation writing location 0x01899000.;Quote:Original post by AntonymYeah that was the problem though another one popped up. The problem occurs at.*** Source Snippet Removed ***The debugger tells me.*** Source Snippet Removed ***What are the values of y and dwBytes when the access violation occurs?   ;  y is 83dwBytes is 384.   