Как использовать UpdateSubresource для обновления текстуры в Direct3d

У меня есть в моем методе CreateDeviceResources следующий код: (метод вызывается в первый раз).

Что мне нужно сделать, чтобы создать метод изменения текстуры? void SetTexture(...textureinput...);

Нужно ли мне запускать приведенный ниже код каждый раз, когда нужно изменить текстуру? или можно как-то просто поменять какие-то данные в памяти?

Я обнаружил, что хотел бы использовать ID3D11DeviceContext::UpdateSubresource, но не смог найти пример того, как его использовать.

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

person Poul K. Sørensen    schedule 03.02.2013    source источник


Ответы (1)


Если вы хотите обновить ту же текстуру во время выполнения, вам нужно использовать Карта

Тип карты должен быть D3D11_MAP_WRITE_DISCARD.

Также ваша текстура должна быть создана с динамическим флагом вместо значения по умолчанию, а флаг доступа к процессору должен быть установлен на D3D11_CPU_ACCESS_WRITE.

Если дает вам доступ к D3D11_MAPPED_SUBRESOURCE , и вы можете установить новые данные, используя pData

В зависимости от случая может быть лучше просто воссоздать текстуру, это зависит от конкретного случая (динамический хорош, если текстура часто меняется)

person mrvux    schedule 04.02.2013