我正在尝试使纹理覆盖三角形而不是颜色,但是纹理初始化似乎有问题...

纹理加载很好,我在Opengl上尝试过,并且效果很好,但是在Directx 11中不起作用。

    void DX11Texture2D::Create(Texture_Data Data, Texture_Desc Desc)
        {
            D3D11_TEXTURE2D_DESC texDesc;
            ZeroMemory(&texDesc, sizeof(texDesc));

            texDesc.Width = Data.width;
            texDesc.Height = Data.height;
            texDesc.MipLevels = 0;
            texDesc.ArraySize = 1;
            texDesc.Format = GetDXTextureFormat(Desc.Format);
            texDesc.SampleDesc.Count = 1;
            texDesc.SampleDesc.Quality = 0;
            texDesc.Usage = D3D11_USAGE_DEFAULT;
            texDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
            texDesc.CPUAccessFlags = 0;
            texDesc.MiscFlags = 0;

            D3D11_SUBRESOURCE_DATA subData;


            subData.pSysMem = Data.databuf;
            subData.SysMemPitch = Data.width * 4;
            subData.SysMemSlicePitch = Data.width * Data.height * 4;


            Core::Internals::DX11Renderer::GetDevice()->CreateTexture2D(&texDesc, &subData, &textureID);

            //TODO: Add a way to disable and enable mip map
            Core::Internals::DX11Renderer::GetDevice()->CreateShaderResourceView(textureID, 0, &resourceView);

            D3D11_SAMPLER_DESC samplerDesc;
            ZeroMemory(&samplerDesc, sizeof(D3D11_SAMPLER_DESC));

            samplerDesc.AddressU = GetDXTextureWrap(Desc.Wrap);
            samplerDesc.AddressV = GetDXTextureWrap(Desc.Wrap);
            samplerDesc.AddressW = GetDXTextureWrap(Desc.Wrap);
            samplerDesc.Filter = GetDXTextureFilter(Desc.Filter);
            samplerDesc.ComparisonFunc = D3D11_COMPARISON_ALWAYS;
            samplerDesc.MinLOD = 0;
            samplerDesc.MaxLOD = D3D11_FLOAT32_MAX;

            Core::Internals::DX11Renderer::GetDevice()->CreateSamplerState(&samplerDesc, &samplerState);


        }
        void DX11Texture2D::Bind(unsigned int index)
        {
            Core::Internals::DX11Renderer::GetContext()->PSSetShaderResources(index, 1, &resourceView);
            Core::Internals::DX11Renderer::GetContext()->PSSetSamplers(index, 1, &samplerState);

        }
        DXGI_FORMAT DX11Texture2D::GetDXTextureFormat(API::TextureFormat format)
        {
            switch (format)
            {
            case API::TextureFormat::R8: return DXGI_FORMAT_R8_UNORM;
            case API::TextureFormat::R8G8: return DXGI_FORMAT_R8G8_UNORM;
            case API::TextureFormat::R8G8B8: return DXGI_FORMAT_R8G8B8A8_UNORM;
            case API::TextureFormat::R8G8B8A8: return DXGI_FORMAT_R8G8B8A8_UNORM;
            default: return DXGI_FORMAT_R8G8B8A8_UNORM;
            }
        }
        D3D11_TEXTURE_ADDRESS_MODE DX11Texture2D::GetDXTextureWrap(API::TextureWrap textureWrap)
        {
            switch (textureWrap)
            {
            case API::TextureWrap::Repeat: return D3D11_TEXTURE_ADDRESS_WRAP;
            case API::TextureWrap::MirroredReapeat: return D3D11_TEXTURE_ADDRESS_MIRROR;
            case API::TextureWrap::ClampToEdge: return D3D11_TEXTURE_ADDRESS_CLAMP;
            case API::TextureWrap::ClampToBorder: return D3D11_TEXTURE_ADDRESS_BORDER;
            default: return D3D11_TEXTURE_ADDRESS_WRAP;
            }
        }
        D3D11_FILTER DX11Texture2D::GetDXTextureFilter(API::TextureFilter textureFilter)
        {
            //TODO: Add more texture filter types to control both min and mag
            switch (textureFilter)
            {
            case API::TextureFilter::Nearest: return D3D11_FILTER_MIN_MAG_MIP_POINT;
            case API::TextureFilter::Linear: return D3D11_FILTER_MIN_MAG_MIP_LINEAR;
            default: return D3D11_FILTER_MIN_MAG_MIP_POINT;
            }
        }

还有我的着色器

Triangle.vs:
    struct VertexInputType
{
    float3 position : POSITION;
    float3 color : COLOR;
    float2 tex : TEXCOORD;

};

struct PixelInputType
{
    float4 position : SV_POSITION;
    float2 tex : TEXCOORD;
};

PixelInputType main(VertexInputType input)
{
    PixelInputType output;


    // Calculate the position of the vertex against the world, view, and projection matrices.
    output.position = float4(input.position,  1);


    // Store the input texture for the pixel shader to use.
    output.tex = input.tex;

    return output;
}

三角形
    struct PixelInputType
{
    float4 position : SV_POSITION;
    float2 tex : TEXCOORD;
};

Texture2D shaderTexture : register(t0);;
SamplerState SampleType : register(s0);;

float4 main(PixelInputType input) : SV_TARGET
{
    return shaderTexture.Sample(SampleType, input.tex);
}

干杯,
Zlixine。

最佳答案

似乎您正在创建具有完整mip贴图链的纹理,但查看初始数据时,您似乎只提供了一个 slice (如果采样器尝试访问另一个 slice ,因为未提供数据,它将为黑色)。

在这种情况下,您应该使用以下命令强制执行单个MIP:

texDesc.MipLevels = 1;

该行:
subData.SysMemSlicePitch = Data.width * Data.height * 4;

不需要,因为在2d纹理的情况下会忽略此参数(您可以将其保留为0或任何值)。

另外,在创建资源时,您应该检查结果代码,例如:
HRESULT hr = Core::Internals::DX11Renderer::GetDevice()->CreateTexture2D(&texDesc, &subData, &textureID);
if FAILED(hr)
{
    //Handle issue if texture creation did fail
}

并确保将D3D11CreateDevice与D3D11_CREATE_DEVICE_DEBUG一起使用,
因此,在调试时,您的Visual Studio输出窗口中将出现有意义的错误消息(如果创建失败,您将得到解释,而不仅仅是获得INVALIDARG的结果,这并不是很有用)

07-28 02:39
查看更多