SlimDX(DirectX10) - 如何在纹理中更改纹理元素?

时间:2009-08-03 17:45:22

标签: directx direct3d slimdx

我尝试更改已加载的纹理的纹素。

我的假设是使用Texture2D :: Map和UnMap函数,但是当我更改给定DataRectangle的数据时没有变化。

我需要一个简单的例子,比如创建一个128x128的纹理,每边都有从黑到白的渐变。

THX

ps:Direct3D 10 C ++示例也可能有所帮助,SlimDX只是一个包装器,几乎完成了相同的功能。

3 个答案:

答案 0 :(得分:2)

这是我的D3D10 2D纹理加载器

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

使用该功能,您需要做的就是将白色纹理传递给黑色纹理。例如,为了写一个256x256 textue,每条水平线比前一行更亮,下面的代码将起作用

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

答案 1 :(得分:0)

确保遵循“资源使用限制”部分中的规则: MSDN: D3D10_USAGE

答案 2 :(得分: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;
    }

这会覆盖每个新帧的缓冲区,你可能想要使用D3D10.MapMode.readwrite或者其他东西,如果你只想写一个纹素

你还需要使用其他一个写函数写入特定点的datarectangle