纹理显示为黑色

时间:2017-07-23 05:46:32

标签: c++ graphics textures game-engine directx-11

我试图让纹理覆盖三角形而不是颜色,但看起来纹理初始化有问题......

纹理加载很好,我尝试使用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;
}

Triangle.ps

    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。

1 个答案:

答案 0 :(得分:2)

看起来你正在创建一个带有完整mip贴图链的纹理,但是看初始数据看起来你只提供一个切片(如果你的采样器试图访问另一个切片,因为没有提供数据,它将是黑色的)

在这种情况下,您应该使用:

强制执行单个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 hresult,这不是很有用)