2009-08-03 19 views
0

J'essaie de changer les texels d'une texture qui est déjà chargé.SlimDX (DirectX10) - Comment changer un texel dans Texture?

Mon hypothèse était d'utiliser les fonctions Texture2D :: Carte et UNMAP, mais il n'y a pas de changement quand je change les données de DataRectangle donné.

je besoin d'un exemple simple comme, créant ainsi une texture de 128x128 avec un gradient du noir au blanc de chaque côté.

Thx

ps: Un exemple Direct3D 10 C++ peut aussi aider, SlimDX est un conteneur et a remplir presque les mêmes fonctions.

Répondre

2

Ceci est mon D3D10 2D texture chargeur

bool D3D10Texture::Init(GFXHandler* pHandler, unsigned int usage, unsigned int width, unsigned int height, unsigned int textureType, bool bMipmapped, void* pTextureData) 
{ 
    mMipmapped  = bMipmapped; 

    //SetData(pHandler, 0); 

    D3D10Handler* pD3DHandler = (D3D10Handler*)pHandler; 
    ID3D10Device* pDevice  = pD3DHandler->GetDevice(); 

    DXGI_SAMPLE_DESC dxgiSampleDesc; 
    dxgiSampleDesc.Count = 1; 
    dxgiSampleDesc.Quality = 0; 

    D3D10_USAGE d3d10Usage; 
    if (usage & RU_All_Dynamic) d3d10Usage = D3D10_USAGE_DYNAMIC; 
    else       d3d10Usage = D3D10_USAGE_DEFAULT; 

    //unsigned int cpuAccess = D3D10_CPU_ACCESS_WRITE; 
    //if ((usage & RU_Buffer_WriteOnly) == 0) cpuAccess |= D3D10_CPU_ACCESS_READ; 

    unsigned int cpuAccess = 0; 
    if (!pTextureData) 
    { 
     cpuAccess = D3D10_CPU_ACCESS_WRITE; 
     //if ((usage & RU_Buffer_WriteOnly) == 0) cpuAccess |= D3D10_CPU_ACCESS_READ; 
    } 

    unsigned int bindFlags = D3D10_BIND_SHADER_RESOURCE; 
    if (usage & RU_Texture_RenderTarget) bindFlags |= D3D10_BIND_RENDER_TARGET; 

    unsigned int miscFlags = 0; 
    if (usage & RU_Texture_AutoGenMipmap) miscFlags |= D3D10_RESOURCE_MISC_GENERATE_MIPS; 

    D3D10_TEXTURE2D_DESC d3d10Texture2DDesc; 
    d3d10Texture2DDesc.Width   = width; 
    d3d10Texture2DDesc.Height   = height; 
    d3d10Texture2DDesc.MipLevels  = GetNumMipMaps(width, height, bMipmapped); 
    d3d10Texture2DDesc.ArraySize  = 1; 
    d3d10Texture2DDesc.Format   = GetD3DFormat((TextureTypes)textureType); 
    d3d10Texture2DDesc.SampleDesc  = dxgiSampleDesc; 
    d3d10Texture2DDesc.Usage   = d3d10Usage; 
    d3d10Texture2DDesc.BindFlags  = D3D10_BIND_SHADER_RESOURCE; 
    d3d10Texture2DDesc.CPUAccessFlags = cpuAccess; 
    d3d10Texture2DDesc.MiscFlags  = miscFlags; 

    //D3D10_SUBRESOURCE_DATA d3d10SubResourceData; 
    //d3d10SubResourceData.pSysMem   = pTextureData; 
    //d3d10SubResourceData.SysMemPitch  = GetPitch(width, (TextureTypes)textureType); 
    //d3d10SubResourceData.SysMemSlicePitch = 0; 

    D3D10_SUBRESOURCE_DATA* pSubResourceData = NULL; 
    if (pTextureData) 
    { 
     pSubResourceData = new D3D10_SUBRESOURCE_DATA[d3d10Texture2DDesc.MipLevels]; 

     char* pTexPos  = (char*)pTextureData; 
     unsigned int pitch = GetPitch(width, (TextureTypes)textureType); 

     unsigned int count = 0; 
     unsigned int max = d3d10Texture2DDesc.MipLevels; 
     while(count < max) 
     { 
      pSubResourceData[count].pSysMem    = pTexPos; 
      pSubResourceData[count].SysMemPitch   = pitch; 
      pSubResourceData[count].SysMemSlicePitch = 0; 

      pTexPos += pitch * height; 
      pitch >>= 1; 
      count++; 
     } 
    } 

    if (FAILED(pDevice->CreateTexture2D(&d3d10Texture2DDesc, pSubResourceData, &mpTexture))) 
    { 
     return false; 
    } 

    if (pSubResourceData) 
    { 
     delete[] pSubResourceData; 
     pSubResourceData = NULL; 
    } 

    mWidth = width; 
    mHeight = height; 
    mFormat = (TextureTypes)textureType; 

    mpTexture->AddRef(); 
    mpTexture->Release(); 

    D3D10_SHADER_RESOURCE_VIEW_DESC d3d10ShaderResourceViewDesc; 
    d3d10ShaderResourceViewDesc.Format      = d3d10Texture2DDesc.Format; 
    d3d10ShaderResourceViewDesc.ViewDimension    = D3D10_SRV_DIMENSION_TEXTURE2D; 
    d3d10ShaderResourceViewDesc.Texture2D.MostDetailedMip = 0; 
    d3d10ShaderResourceViewDesc.Texture2D.MipLevels   = GetNumMipMaps(width, height, bMipmapped); 

    if (FAILED(pDevice->CreateShaderResourceView(mpTexture, &d3d10ShaderResourceViewDesc, &mpView))) 
    { 
     return false; 
    } 

    ResourceRecorder::Instance()->AddResource(this); 
    return true; 
} 

Avec cette fonction tout ce que vous devez faire est de passer dans le petit morceau à la texture noire. Par exemple, pour écrire un 256x256 textue chaque ligne horizontale étant un plus lumineux que la ligne précédente le code suivant fonctionnera

int* pTexture = new int[256 * 256]; 
int count = 0; 
while(count < 256) 
{ 
    int count2 = 0; 
    while(count2 < 256) 
    { 
     pTexture[(count * 256) + count2] = 0xff000000 | (count << 16) | (count << 8) | count; 
     count2++; 
    } 
    count++; 
} 
+0

Merci, ce fut une aide pour moi. – plucked

0

Assurez-vous que vous suivez les règles de la section « Restrictions d'utilisation des ressources »: MSDN: D3D10_USAGE

+0

Merci, ces restrictions sont très difficiles à comprendre à la première fois, mais sachez que je sais quelques points pourquoi mon code ne fonctionne pas. – plucked

0
public void NewData(byte[] newData) 
    { 
     DataRectangle mappedTex = null; 
     //assign and lock the resource 
     mappedTex = pTexture.Map(0, D3D10.MapMode.WriteDiscard, D3D10.MapFlags.None); 
     // if unable to hold texture 
     if (!mappedTex.Data.CanWrite) 
     { 
      throw new ApplicationException("Cannot Write to the Texture"); 
     } 
     // write new data to the texture 
     mappedTex.Data.WriteRange<byte>(newData); 
     // unlock the resource 
     pTexture.Unmap(0); 
     if (samplerflag) 
      temptex = newData; 
    } 

ce tampon écrase le sur chaque nouveau cadre, vous pouvez utiliser un D3D10.MapMode.readwrite ou quelque chose si ur n'essayer d'écrire un texel

vous devrez également écrire au datarectangle en un point spécifique en utilisant vous l'une des autres fonctions d'écriture