Search code examples
directxdirect3dslimdx

SlimDX (DirectX10) - How to change a texel in Texture?


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.


Solution

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