views:

605

answers:

3

Hi,

I try to change the texels of a Texture which is already loaded.

My assumption was to use the Texture2D::Map and UnMap functions, but there is no change when I change the data of given DataRectangle.

I need a simple example like, creating a texture of 128x128 with a gradient from black to white from each side.

Thx

ps: A Direct3D 10 C++ example may also help, SlimDX is only a wrapper and has nearly complete the same functions.

+1  A: 

This is my D3D10 2D texture loader

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;
}

With that function all you need to do is pass in the whit to black texture. For example to write a 256x256 textue with each horizontal line being one brighter than the previous line the following code will work

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++;
}
Goz
Thank you, it was a help for me.
plucked
A: 

Make sure you follow the rules in the "Resource Usage Restrictions" section: MSDN: D3D10_USAGE

gatorfax
Thank you, those restrictions are very hard to understand at the first time, but know I know some points why my code might not work.
plucked
A: 
    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;
    }

this overwrites the buffer on every new frame, you may want to use a D3D10.MapMode.readwrite or something if ur only trying to write one texel

you will also need to write to the datarectangle in a specific point using one of the other write functions