我已经调试了大约一天,一切似乎都还好。我正在尝试绘制一个简单的图像,但没有任何显示。我有一个可以编译的Pixel Shader和Vertex Shader。

我将提供所有代码,任何帮助将不胜感激。

主C++文件:

#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);
}

像素着色器
float4 main(float4 position : SV_POSITION, float4 color : COLOR) : SV_TARGET
{
    return color;
}

顶点着色器
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;
}

最佳答案

您发布的代码在大多数Direct3D调用中都缺少HRESULT的错误检查。如果COM调用返回void,则不必处理该错误,否则,您可以处理。您可以使用SUCCEEDED宏,FAILED宏或ThrowIfFailed帮助器来执行此操作。我敢打赌,至少有一个电话失败了,而且您没有注意到,因为您没有检查失败的结果。

其次,您应该通过传递D3D11_CREATE_DEVICE_DEBUG作为第四个参数来启用调试设备。然后在调试输出中查找ERROR或CORRUPTION消息。参见this post

关于c++ - DirectX 11. Hello Triangle无法渲染,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/37842927/

10-10 20:23