简体   繁体   中英

DirectX 11. Hello Triangle not rendering

I've been debugging this for about a day now and everything seems okay. Im trying to get a simple tringle to render, but nothing is showing up. I have a Pixel Shader and a Vertex Shader which is compiling okay.

I will supply all of the code, any help would be greatly appreciated.

Main C++ File:

#include <windows.h>
#include <D3D11_1.h>

static int ScreenWidth = 1280;
static int ScreenHeight = 720;

static bool GlobalRunning;

static ID3D11Device *Device;
static ID3D11DeviceContext *DeviceContext;
static IDXGISwapChain1 *SwapChain;
static ID3D11RenderTargetView *RenderTargetView;

#define Assert(Expression) if(!(Expression)) { *(int *)0 = 0;}

struct vec3
{
    float X;
    float Y;
    float Z;
};

struct vec4
{
    float X;
    float Y;
    float Z;
    float W;
};

struct vertex
{
    vec3 Position;
    vec4 Color;
};

static int
SafeTruncateUInt64(LONG Value)
{
    Assert(Value <= 0xFFFFFFFF);
    int Result = (int)Value;
    return(Result);
}

struct read_file_result
{
    void *Contents;
    int ContentsSize;
};

static read_file_result 
Win32LoadEntireFile(char *Filename)
{
    read_file_result Result = {};

    HANDLE File = CreateFileA(Filename, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);

    if(File != INVALID_HANDLE_VALUE)
    {
        LARGE_INTEGER FileSize;
        if(GetFileSizeEx(File, &FileSize))
        {
            int FileSize32 = SafeTruncateUInt64(FileSize.QuadPart);
            Result.Contents = VirtualAlloc(0, FileSize32, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE);
            if(Result.Contents)
            {
                DWORD BytesRead;
                if(ReadFile(File, Result.Contents, FileSize32, &BytesRead, 0) && BytesRead == FileSize32)
                {
                    Result.ContentsSize = FileSize32;
                }
                else
                {
                    // TODO(zak): Logging
                }

            }
            else
            {
                // TODO(zak): Logging
            }
        }
        else
        {
            // TODO(zak): Logging
        }
    }
    else
    {
        // TODO(zak): Logging
    }

    return(Result);
}

static LRESULT CALLBACK
Win32MainWindowCallback(HWND Window,
                        UINT Message,
                        WPARAM WParam,
                        LPARAM LParam)
{
    LRESULT Result = 0;

    switch(Message)
    {
        case WM_ACTIVATEAPP:
        {
            // TODO(zak): Handle this
        } break;

        case WM_SIZE:
        {
            ScreenWidth = LOWORD(LParam);
            ScreenHeight = HIWORD(LParam);

            RenderTargetView->Release();

            SwapChain->ResizeBuffers(0, ScreenWidth, ScreenHeight, DXGI_FORMAT_UNKNOWN, 0);

            ID3D11Texture2D *BackBuffer;
            if(SwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void **)&BackBuffer) == S_OK)
            {
                Device->CreateRenderTargetView(BackBuffer, 0, &RenderTargetView);
                BackBuffer->Release();
            }
        } break;

        case WM_QUIT:
        {
            GlobalRunning = false;
        } break;

        case WM_DESTROY:
        {
            GlobalRunning = false;
        } break;

        default:
        {
            Result = DefWindowProcA(Window, Message, WParam, LParam);
        }
    }

    return(Result);
}


int CALLBACK
WinMain(HINSTANCE Instance,
        HINSTANCE PrevInstance,
        LPSTR CommandLine,
        int ShowCode)
{
    WNDCLASSA WindowClass = {};
    WindowClass.style = CS_HREDRAW|CS_VREDRAW;
    WindowClass.lpfnWndProc = Win32MainWindowCallback;
    WindowClass.hInstance = Instance;
    WindowClass.lpszClassName = "DXPlaygroundWindowClass";

    if(RegisterClassA(&WindowClass))
    {
        RECT WindowRect;
        WindowRect.top = 0;
        WindowRect.bottom = ScreenHeight;
        WindowRect.left = 0;
        WindowRect.right = ScreenWidth;

        AdjustWindowRect(&WindowRect, WS_OVERLAPPEDWINDOW, 0);

        HWND Window =
            CreateWindowExA(0,
                            WindowClass.lpszClassName,
                            "D3D Playground",
                            WS_OVERLAPPEDWINDOW,
                            CW_USEDEFAULT, CW_USEDEFAULT,
                            WindowRect.right - WindowRect.left,
                            WindowRect.bottom - WindowRect.top,
                            0, 0, Instance, 0);

        if(Window)
        {
            D3D_FEATURE_LEVEL FeatureLevelsRequested[3]
            {
                D3D_FEATURE_LEVEL_11_0,
                D3D_FEATURE_LEVEL_10_1,
                D3D_FEATURE_LEVEL_10_0,
            };

            D3D_FEATURE_LEVEL FeatureLevelReturned;

            if(D3D11CreateDevice(0,
                                 D3D_DRIVER_TYPE_HARDWARE,
                                 0,
                                 0,
                                 FeatureLevelsRequested,
                                 3,
                                 D3D11_SDK_VERSION,
                                 &Device,
                                 &FeatureLevelReturned,
                                 &DeviceContext) == S_OK)
            {
                IDXGIFactory2 *Factory;
                if(CreateDXGIFactory(__uuidof(IDXGIFactory2), (void **)&Factory) == S_OK)
                {
                    DXGI_SWAP_CHAIN_DESC1 SwapChainDescription = {};
                    SwapChainDescription.Width = ScreenWidth;
                    SwapChainDescription.Height = ScreenHeight;
                    SwapChainDescription.Format = DXGI_FORMAT_B8G8R8A8_UNORM;

                    DXGI_SAMPLE_DESC SampleDescription = {};
                    SampleDescription.Count = 1;
                    SampleDescription.Quality = 0;

                    SwapChainDescription.SampleDesc = SampleDescription;
                    SwapChainDescription.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
                    SwapChainDescription.BufferCount = 2;
                    SwapChainDescription.Scaling = DXGI_SCALING_STRETCH;
                    SwapChainDescription.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;

                    if(Factory->CreateSwapChainForHwnd(Device, Window,
                                                       &SwapChainDescription,
                                                       0, 0, &SwapChain) == S_OK)
                    {
                        ID3D11Texture2D *BackBuffer;
                        if(SwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D),
                                                (void **)&BackBuffer) == S_OK)
                        {
                            Device->CreateRenderTargetView(BackBuffer, 0, &RenderTargetView);
                            BackBuffer->Release();
                        }

                        ShowWindow(Window, SW_SHOWNORMAL);

                        read_file_result VertexShaderFile = Win32LoadEntireFile("shaders/testvertex.fxo");
                        read_file_result PixelShaderFile = Win32LoadEntireFile("shaders/testpixel.fxo");

                        ID3D11VertexShader *VertexShader;
                        ID3D11PixelShader *PixelShader;

                        Device->CreateVertexShader(VertexShaderFile.Contents, 
                                VertexShaderFile.ContentsSize, 0, &VertexShader);

                        Device->CreatePixelShader(PixelShaderFile.Contents,
                                PixelShaderFile.ContentsSize, 0, &PixelShader);

                        DeviceContext->VSSetShader(VertexShader, 0, 0);
                        DeviceContext->PSSetShader(PixelShader, 0, 0);

                        D3D11_INPUT_ELEMENT_DESC ied[] =
                        {
                            {"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0},
                            {"COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0},
                        };

                        ID3D11InputLayout *Layout;
                        Device->CreateInputLayout(ied, 2, VertexShaderFile.Contents, VertexShaderFile.ContentsSize, &Layout);
                        DeviceContext->IASetInputLayout(Layout);

                        vertex OurVerticies[3] = {};
                        OurVerticies[0].Position.Y = 0.5f;
                        OurVerticies[0].Color.X = 1.0f;
                        OurVerticies[0].Color.W = 1.0f;
                        OurVerticies[1].Position.X = 0.45f;
                        OurVerticies[1].Position.Y = -0.5f;
                        OurVerticies[1].Color.Y = 1.0f;
                        OurVerticies[1].Color.W = 1.0f;
                        OurVerticies[2].Position.X = -0.45f;
                        OurVerticies[2].Position.Y = -0.5f;
                        OurVerticies[2].Color.Z = 1.0f;
                        OurVerticies[2].Color.W = 1.0f;

                        ID3D11Buffer *VertexBuffer = 0;

                        D3D11_BUFFER_DESC BufferDescription = {};
                        BufferDescription.Usage = D3D11_USAGE_DYNAMIC;
                        BufferDescription.ByteWidth = sizeof(vertex) * 3;
                        BufferDescription.BindFlags = D3D11_BIND_VERTEX_BUFFER;
                        BufferDescription.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;

                        Device->CreateBuffer(&BufferDescription, 0, &VertexBuffer);

                        D3D11_MAPPED_SUBRESOURCE MappedSubresource;
                        DeviceContext->Map(VertexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &MappedSubresource);
                        CopyMemory(MappedSubresource.pData, OurVerticies, sizeof(OurVerticies));
                        DeviceContext->Unmap(VertexBuffer, 0);


                        GlobalRunning = true;

                        while(GlobalRunning)
                        {                                            
                            MSG Message;

                            while(PeekMessageA(&Message, 0, 0, 0, PM_REMOVE))
                            {
                                TranslateMessage(&Message);
                                DispatchMessageA(&Message);
                            }

                            FLOAT ClearColor[] = {0.0f, 0.0f, 1.0f, 1.0f};
                            DeviceContext->ClearRenderTargetView(RenderTargetView, ClearColor);
                            DeviceContext->OMSetRenderTargets(1, &RenderTargetView, 0);

                            UINT Stride = sizeof(vertex);
                            UINT Offset = 0;
                            DeviceContext->IASetVertexBuffers(0, 1, &VertexBuffer, &Stride, &Offset);

                            DeviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);



                            DeviceContext->Draw(3, 0); 

                            SwapChain->Present(1, 0);

                        }
                    }
                    else
                    {
                        // TODO(zak): Logging
                    }
                }
                else
                {
                    // TODO(zak): Logging
                }
            }
            else
            {
                // TODO(zak): Logging
            }
        }
        else
        {
            // TODO(zak): Logging
        }
    }
    else
    {
        // TODO(zak): Logging
    }

    return(0);
}

Pixel Shader

float4 main(float4 position : SV_POSITION, float4 color : COLOR) : SV_TARGET
{
    return color;
}

Vertex Shader

struct VOut
{
    float4 position : SV_POSITION;
    float4 color : COLOR;
};

VOut main(float4 position : POSITION, float4 color : COLOR)
{
    VOut output;

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

    return output;
}

The code you've posted is missing error checking of the HRESULT on most of the Direct3D calls. If a COM call returns a void you don't have to handle the error, otherwise you do. You can do this with the SUCCEEDED macro, the FAILED macro, or with the ThrowIfFailed helper. I'd bet at least one of your calls is failing and you don't notice because you aren't checking for a failure result.

Second, you should enable the Debug device by passing D3D11_CREATE_DEVICE_DEBUG as the 4th parameter. Then look for ERROR or CORRUPTION messages in your debug output. See this post .

Not sure where you got your original "hello world" tutorial, but you should take a look at the Direct3D Game VS Templates and the DirectX Tool Kit .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM