Poul K. Sørensen
Poul K. Sørensen

Reputation: 17540

How to use UpdateSubresource to update the texture in Direct3d

I have in my CreateDeviceResources method the following code: (the method is called at initial once).

What do i need to do to create a method change the texture? void SetTexture(...textureinput...);

Do i need to run below code everytime a texture needs to be changed? or can I somehow just change some data in memory?

I have found that I would like to use ID3D11DeviceContext::UpdateSubresource, but havent been able to find a sample on how to use it.

  auto textureData = reader->ReadData("SIn.Win8\\texturedata.bin");
        D3D11_SUBRESOURCE_DATA textureSubresourceData = {0};
        textureSubresourceData.pSysMem = textureData->Data;

        // Specify the size of a row in bytes, known a priori about the texture data.
        textureSubresourceData.SysMemPitch = 1024;

        // As this is not a texture array or 3D texture, this parameter is ignored.
        textureSubresourceData.SysMemSlicePitch = 0;

        // Create a texture description from information known a priori about the data.
        // Generalized texture loading code can be found in the Resource Loading sample.
        D3D11_TEXTURE2D_DESC textureDesc = {0};
        textureDesc.Width = 256;
        textureDesc.Height = 256;
        textureDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
        textureDesc.Usage = D3D11_USAGE_DEFAULT;
        textureDesc.CPUAccessFlags = 0;
        textureDesc.MiscFlags = 0;

        // Most textures contain more than one MIP level.  For simplicity, this sample uses only one.
        textureDesc.MipLevels = 1;

        // As this will not be a texture array, this parameter is ignored.
        textureDesc.ArraySize = 1;

        // Don't use multi-sampling.
        textureDesc.SampleDesc.Count = 1;
        textureDesc.SampleDesc.Quality = 0;

        // Allow the texture to be bound as a shader resource.
        textureDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;

        ComPtr<ID3D11Texture2D> texture;
        DX::ThrowIfFailed(
            m_d3dDevice->CreateTexture2D(
                &textureDesc,
                &textureSubresourceData,
                &texture
                )
            );

        // Once the texture is created, we must create a shader resource view of it
        // so that shaders may use it.  In general, the view description will match
        // the texture description.
        D3D11_SHADER_RESOURCE_VIEW_DESC textureViewDesc;
        ZeroMemory(&textureViewDesc, sizeof(textureViewDesc));
        textureViewDesc.Format = textureDesc.Format;
        textureViewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
        textureViewDesc.Texture2D.MipLevels = textureDesc.MipLevels;
        textureViewDesc.Texture2D.MostDetailedMip = 0;

        ComPtr<ID3D11ShaderResourceView> textureView;
        DX::ThrowIfFailed(
            m_d3dDevice->CreateShaderResourceView(
                texture.Get(),
                &textureViewDesc,
                &textureView
                )
            );

        // Once the texture view is created, create a sampler.  This defines how the color
        // for a particular texture coordinate is determined using the relevant texture data.
        D3D11_SAMPLER_DESC samplerDesc;
        ZeroMemory(&samplerDesc, sizeof(samplerDesc));

        samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;

        // The sampler does not use anisotropic filtering, so this parameter is ignored.
        samplerDesc.MaxAnisotropy = 0;

        // Specify how texture coordinates outside of the range 0..1 are resolved.
        samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
        samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
        samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;

        // Use no special MIP clamping or bias.
        samplerDesc.MipLODBias = 0.0f;
        samplerDesc.MinLOD = 0;
        samplerDesc.MaxLOD = D3D11_FLOAT32_MAX;

        // Don't use a comparison function.
        samplerDesc.ComparisonFunc = D3D11_COMPARISON_NEVER;

        // Border address mode is not used, so this parameter is ignored.
        samplerDesc.BorderColor[0] = 0.0f;
        samplerDesc.BorderColor[1] = 0.0f;
        samplerDesc.BorderColor[2] = 0.0f;
        samplerDesc.BorderColor[3] = 0.0f;

        ComPtr<ID3D11SamplerState> sampler;
        DX::ThrowIfFailed(
            m_d3dDevice->CreateSamplerState(
                &samplerDesc,
                &sampler
                )
            );

Upvotes: 3

Views: 6941

Answers (1)

mrvux
mrvux

Reputation: 8963

If you want to update the same texture at runtime, you need to use Map

Maptype needs to be D3D11_MAP_WRITE_DISCARD

Also your texture needs to be created with the Dynamic flag instead of default, and cpu access flag needs to be set to D3D11_CPU_ACCESS_WRITE

If gives you access to D3D11_MAPPED_SUBRESOURCE , and you can set the new data using pData

Depending on the case it can be nicer to just recreate a texture, it's on a case by case basis (dynamic is nice if texture changes often)

Upvotes: 2

Related Questions