在D3D11 2D中发布工程图纹理

时间:2019-05-13 00:42:20

标签: c++ directx-11 texture2d

由于某种原因,我的纹理无法在D3D11中正确渲染到窗口上。它没有正确显示纹理,而是对整个充满米色杂物的样品进行了采样,而这些都是全彩色,而不是实际对纹理进行采样。

#include <Windows.h>
#include <D3D11.h>
#include <D3DX11.h>
#include <D3DX10.h>

#pragma comment(lib, "d3d11.lib")
#pragma comment(lib, "d3dx11.lib")
#pragma comment(lib, "d3dx10.lib")

struct vertex_t
{
    vertex_t( float x, float y, float z, float r, float g, float b, float a ) : x( x ), y( y ), z( z ), r( r ), g( g ), b( b ), a( a )
    { }

    float x = 0.f, y = 0.f, z = 0.f,
          u = 1.f, v = 1.f,
          r = 0.f, g = 0.f, b = 0.f, a = 0.f;
};

constexpr auto WIDTH = 1280, HEIGHT = 720;

HINSTANCE hApplicationInstance = nullptr;
HWND hwWindow = nullptr;

IDXGISwapChain *pSwapChain = nullptr;
ID3D11Device *pDevice = nullptr;
ID3D11DeviceContext *pContext = nullptr;
ID3D11RenderTargetView *pRenderTargetView = nullptr;
ID3D11Texture2D *pDepthStencilBuffer = nullptr;
ID3D11DepthStencilView *pDepthStencilView = nullptr;
ID3D11SamplerState *pSamplerState = nullptr;

ID3D11VertexShader *pVertexShader = nullptr;
ID3D11PixelShader *pPixelShader = nullptr;
ID3D10Blob *pVertexShaderBuffer = nullptr;
ID3D10Blob *pPixelShaderBuffer = nullptr;
ID3D11Buffer *pVertexBuffer = nullptr;
ID3D11InputLayout *pVertexLayout = nullptr;
ID3D11ShaderResourceView *pTexture;

bool CreateRenderTarget( );
int RenderLoop( );
LRESULT CALLBACK WindowProcessor( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam );

bool Initialize( );
void Release( );
bool CreateScene( );
void Draw( );

int WINAPI WinMain( HINSTANCE hInstance,
                    HINSTANCE hPrevInstance,
                    LPSTR lpCmdLine,
                    int nShowCmd )
{
    if ( CreateRenderTarget( )
        && Initialize( )
        && CreateScene( ) )
        RenderLoop( );
    else
        return EXIT_FAILURE;

    Release( );
    return EXIT_SUCCESS;
}

bool CreateRenderTarget( )
{
    WNDCLASSEX _WindowClass { sizeof( WNDCLASSEX ), CS_HREDRAW | CS_VREDRAW, WindowProcessor, 0, 0, hApplicationInstance, nullptr, nullptr, nullptr, nullptr, L"Window", nullptr };

    if ( !RegisterClassEx( &_WindowClass ) )
        return false;

    return ( hwWindow = CreateWindowEx( NULL, L"Window", L"Window Title", WS_OVERLAPPEDWINDOW | WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, WIDTH, HEIGHT,
                                        nullptr, nullptr, hApplicationInstance, nullptr ) ) != nullptr;
}

bool Initialize( )
{
    DXGI_MODE_DESC _BufferDescription { };
    DXGI_SWAP_CHAIN_DESC _SwapChainDescription { };
    D3D11_SAMPLER_DESC _SamplerDescription { };
    ID3D11Texture2D *pBackBuffer = nullptr;
    D3D11_TEXTURE2D_DESC _DepthStencilDescription;

    _BufferDescription.Width = WIDTH;
    _BufferDescription.Height = HEIGHT;
    _BufferDescription.RefreshRate.Numerator = 60;
    _BufferDescription.RefreshRate.Denominator = 1;
    _BufferDescription.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
    _BufferDescription.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
    _BufferDescription.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;

    _SwapChainDescription.BufferDesc = _BufferDescription;
    _SwapChainDescription.SampleDesc.Count = 1;
    _SwapChainDescription.SampleDesc.Quality = 0;
    _SwapChainDescription.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
    _SwapChainDescription.BufferCount = 1;
    _SwapChainDescription.OutputWindow = hwWindow;
    _SwapChainDescription.Windowed = TRUE;
    _SwapChainDescription.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;

    D3D11CreateDeviceAndSwapChain( nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, NULL, nullptr, NULL,
                                   D3D11_SDK_VERSION, &_SwapChainDescription, &pSwapChain, &pDevice, nullptr, &pContext );

    pSwapChain->GetBuffer( 0, __uuidof( ID3D11Texture2D), reinterpret_cast< void ** >( &pBackBuffer ) );
    pDevice->CreateRenderTargetView( pBackBuffer, nullptr, &pRenderTargetView );
    pBackBuffer->Release( );

    _DepthStencilDescription.Width = WIDTH;
    _DepthStencilDescription.Height = HEIGHT;
    _DepthStencilDescription.MipLevels = 1;
    _DepthStencilDescription.ArraySize = 1;
    _DepthStencilDescription.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
    _DepthStencilDescription.SampleDesc.Count = 1;
    _DepthStencilDescription.SampleDesc.Quality = 0;
    _DepthStencilDescription.Usage = D3D11_USAGE_DEFAULT;
    _DepthStencilDescription.BindFlags = D3D11_BIND_DEPTH_STENCIL;
    _DepthStencilDescription.CPUAccessFlags = 0;
    _DepthStencilDescription.MiscFlags = 0;

    pDevice->CreateTexture2D( &_DepthStencilDescription, NULL, &pDepthStencilBuffer );
    pDevice->CreateDepthStencilView( pDepthStencilBuffer, NULL, &pDepthStencilView );
    pContext->OMSetRenderTargets( 1, &pRenderTargetView, pDepthStencilView );

    _SamplerDescription.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
    _SamplerDescription.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
    _SamplerDescription.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
    _SamplerDescription.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
    _SamplerDescription.ComparisonFunc = D3D11_COMPARISON_NEVER;
    _SamplerDescription.MinLOD = 0;
    _SamplerDescription.MaxLOD = D3D11_FLOAT32_MAX;

    pDevice->CreateSamplerState( &_SamplerDescription, &pSamplerState );

    return true;
}

void Release( )
{
    pSwapChain->Release( );
    pDevice->Release( );
    pContext->Release( );
    pRenderTargetView->Release( );
    pVertexBuffer->Release( );
    pVertexShader->Release( );
    pPixelShader->Release( );
    pVertexShaderBuffer->Release( );
    pPixelShaderBuffer->Release( );
    pVertexLayout->Release( );
}

bool CreateScene( )
{
    vertex_t _Vertices[ ] =
    {
        vertex_t( -0.5f, 0.5f, 0.5f, 0.f, 0.f, 1.f, 1.f ),
        vertex_t( 0.5f, 0.5f, 0.5f, 0.f, 1.f, 0.f, 1.f ),
        vertex_t( -0.5f, -0.5f, 0.5f, 1.f, 0.f, 0.f, 1.f ),
        vertex_t( 0.5f, -0.5f, 0.5f, 1.f, 0.f, 0.f, 1.f ),
    };
    D3D11_BUFFER_DESC _VertexBufferDescription { };
    D3D11_SUBRESOURCE_DATA _VertexBufferData { };
    D3D11_VIEWPORT _Viewport { };
    D3D11_INPUT_ELEMENT_DESC _Layout[ ] =
    {
        { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
        { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
        { "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 20, D3D11_INPUT_PER_VERTEX_DATA, 0 },
    };

    D3DX11CompileFromFile( LR"(C:\Users\K\Documents\Visual Studio 2019\Projects\D3D11\D3D11\Source\Shaders.hlsl)", nullptr, nullptr, "vertex_shader", "vs_4_0", 0, 0, nullptr, &pVertexShaderBuffer, nullptr, nullptr );
    D3DX11CompileFromFile( LR"(C:\Users\K\Documents\Visual Studio 2019\Projects\D3D11\D3D11\Source\Shaders.hlsl)", nullptr, nullptr, "pixel_shader", "ps_4_0", 0, 0, nullptr, &pPixelShaderBuffer, nullptr, nullptr );
    D3DX11CreateShaderResourceViewFromFile( pDevice, LR"(C:\Users\K\Desktop\image.jpg)", nullptr, nullptr, &pTexture, nullptr );

    pDevice->CreateVertexShader( pVertexShaderBuffer->GetBufferPointer( ), pVertexShaderBuffer->GetBufferSize( ), NULL, &pVertexShader );
    pDevice->CreatePixelShader( pPixelShaderBuffer->GetBufferPointer( ), pPixelShaderBuffer->GetBufferSize( ), NULL, &pPixelShader );
    pContext->VSSetShader( pVertexShader, nullptr, 0 );
    pContext->PSSetShader( pPixelShader, nullptr, 0 );

    _VertexBufferDescription.Usage = D3D11_USAGE_DEFAULT;
    _VertexBufferDescription.ByteWidth = sizeof( vertex_t ) * ARRAYSIZE( _Vertices );
    _VertexBufferDescription.BindFlags = D3D11_BIND_VERTEX_BUFFER;
    _VertexBufferDescription.CPUAccessFlags = 0;
    _VertexBufferDescription.MiscFlags = 0;

    _VertexBufferData.pSysMem = _Vertices;
    pDevice->CreateBuffer( &_VertexBufferDescription, &_VertexBufferData, &pVertexBuffer );

    auto uStride = sizeof( vertex_t ), uOffset = 0u;
    pContext->IASetVertexBuffers( 0, 1, &pVertexBuffer, &uStride, &uOffset );

    pDevice->CreateInputLayout( _Layout, ARRAYSIZE( _Layout ), pVertexShaderBuffer->GetBufferPointer( ), pVertexShaderBuffer->GetBufferSize( ), &pVertexLayout );
    pContext->IASetInputLayout( pVertexLayout );
    pContext->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP );

    _Viewport.TopLeftX = 0;
    _Viewport.TopLeftY = 0;
    _Viewport.Width = WIDTH;
    _Viewport.Height = HEIGHT;

    pContext->RSSetViewports( 1, &_Viewport );
    return true;
}

void Draw( )
{
    pContext->ClearRenderTargetView( pRenderTargetView, D3DXCOLOR( 0.f, 0.f, 0.f, 0.f ) );
    pContext->ClearDepthStencilView( pDepthStencilView, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.f, 0 );
    pContext->PSSetShaderResources( 0, 1, &pTexture );
    pContext->PSSetSamplers( 0, 1, &pSamplerState );
    pContext->Draw( 6, 0 );
    pSwapChain->Present( 0, 0 );
}

int RenderLoop( )
{
    MSG _Message { };

    while ( true )
    {
        if ( PeekMessage( &_Message, nullptr, 0, 0, PM_REMOVE ) )
        {
            if ( _Message.message == WM_QUIT )
                break;

            TranslateMessage( &_Message );
            DispatchMessage( &_Message );
        }
        else
            Draw( );
    }

    return _Message.wParam;
}

LRESULT CALLBACK WindowProcessor( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
    return DefWindowProc( hWnd, uMsg, wParam, lParam );
}

顶点和像素着色器:

struct vertex_t
{
    float4 position : SV_POSITION;
    float4 texture_coordinates : TEXCOORD;
    float4 color : COLOR;
};

Texture2D shader_texture;
SamplerState sampler_type;

vertex_t vertex_shader( float4 position : POSITION, float4 texture_coordinates : TEXCOORD, float4 color : COLOR )
{
    vertex_t output;

    output.position = position;
    output.texture_coordinates = texture_coordinates;
    output.color = color;

    return output;
}

float4 pixel_shader( vertex_t input ) : SV_TARGET
{
    return shader_texture.Sample( sampler_type, input.texture_coordinates );
}

我尝试去除结构的颜色部分仍然没有运气。我是D3D11的新手,我不确定自己在做什么错。这是运行时的屏幕截图:https://imgur.com/VKPlxAd

我试图更改交换链缓冲区描述的缩放模式,但这似乎也没有作用。

0 个答案:

没有答案