【问题标题】:Confusion about Texture2D and ShaderResourceViews关于 Texture2D 和 ShaderResourceViews 的困惑
【发布时间】:2017-12-04 19:34:35
【问题描述】:

我是 Direct3D11 的新手,我目前正尝试使用我在网上找到的代码在我的代码中以编程方式创建纹理:

// Some Constants
int w = 256;
int h = 256;
int bpp = 4;
int *buf = new int[w*h];

//declarations
ID3D11Texture2D* tex;
D3D11_TEXTURE2D_DESC sTexDesc;
D3D11_SUBRESOURCE_DATA tbsd;

// filling the image
for (int i = 0; i<h; i++)
    for (int j = 0; j<w; j++)
    {
        if ((i & 32) == (j & 32))
            buf[i*w + j] = 0x00000000;
        else
            buf[i*w + j] = 0xffffffff;
    }

// setting up D3D11_SUBRESOURCE_DATA 
tbsd.pSysMem = (void *)buf;
tbsd.SysMemPitch = w*bpp;
tbsd.SysMemSlicePitch = w*h*bpp; // Not needed since this is a 2d texture

// initializing sTexDesc
sTexDesc.Width = w;
sTexDesc.Height = h;
sTexDesc.MipLevels = 1;
sTexDesc.ArraySize = 1;
sTexDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
sTexDesc.SampleDesc.Count = 1;
sTexDesc.SampleDesc.Quality = 0;
sTexDesc.Usage = D3D11_USAGE_DEFAULT;
sTexDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
sTexDesc.CPUAccessFlags = 0;
sTexDesc.MiscFlags = 0;

hr = m_pd3dDevice->CreateTexture2D(&sTexDesc, &tbsd, &tex);

这一切都很好,但我对如何将它实际加载到着色器中有点困惑。下面我初始化了这个ID3D11ShaderResourceView:

        ID3D11ShaderResourceView*           m_pTextureRV = nullptr;

我在 Microsoft 教程中发现我需要使用 CreateShaderResourceView。但我究竟如何使用它?我试过这个:

        hr = m_pd3dDevice->CreateShaderResourceView(tex, NULL , m_pTextureRV);

但它给了我一个错误,告诉我 m_pTextureRV 不是该函数的有效参数。我在这里做错了什么?

【问题讨论】:

    标签: resources shader direct3d texture2d direct3d11


    【解决方案1】:

    调用该函数的正确方法是:

    hr = m_pd3dDevice->CreateShaderResourceView(tex, nullptr, &m_pTextureRV);
    

    请记住,ID3D11ShaderResourceView* 是一个指向接口的指针。你需要一个指向指针的指针来获取一个新的实例。

    您真的应该考虑使用像Microsoft::WRL::ComPtr 这样的 COM 智能指针,而不是这些接口的原始指针。

    为纹理对象创建着色器资源视图后,您需要将其与 HLSL 期望在其中找到它的任何插槽相关联。因此,例如,如果您要将 HLSL 源文件编写为:

    Texture2D texture : register( t0 );
    SamplerState sampler: register( s0 );
    
    float4 PS(float2 tex : TEXCOORD0) : SV_Target
    {
        return texture.Sample( sampler, tex );
    }
    

    然后将其编译为 Pixel Shader,并通过 PSSetShader 将其绑定到渲染管道。然后你需要打电话:

    ID3D11ShaderResourceView* srv[1] = { m_pTextureRV };
    m_pImmediateContext->PSSetShaderResources( 0, 1, srv );
    

    当然,您还需要绑定ID3D11SamplerState* 采样器:

    ID3D11SamplerState* m_pSamplerLinear = nullptr;
    
    D3D11_SAMPLER_DESC sampDesc = {};
    sampDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
    sampDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
    sampDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
    sampDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
    sampDesc.ComparisonFunc = D3D11_COMPARISON_NEVER;
    sampDesc.MinLOD = 0;
    sampDesc.MaxLOD = D3D11_FLOAT32_MAX;
    hr = m_pd3dDevice->CreateSamplerState( &sampDesc, &m_pSamplerLinear );
    

    那么当你要画的时候:

    m_pImmediateContext->PSSetSamplers( 0, 1, &m_pSamplerLinear );
    

    我强烈建议您查看DirectX Tool Kit 和tutorials。

    【讨论】:

    • 非常感谢查克!我一定会研究 COM 智能指针。
    猜你喜欢
    • 2014-10-30
    • 2011-12-13
    • 2012-03-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-17
    • 2020-03-06
    • 2016-03-16
    相关资源
    最近更新 更多