关于获取“ Hello三角形”程序来渲染三角形的问题

问题描述 投票:0回答:1

编辑:抱歉,这是我第一次在这里发布。我现在添加了“ start_console”文件,以便您可以对其进行构建。抱歉,未指定问题。我的问题是我希望三角形在打开的窗口中呈现,但不是。

我已经尝试调试了一段时间,但找不到问题。非常感谢您的帮助:)除事件处理程序外,所有文件都发布在下面。我尝试启用D3D11_CREATE_DEVICE_DEBUG标志,并在每个HRESULT之后添加FAILED()函数,但没有发现任何错误。

main.cpp

//Headers
#define WIN32_LEAN_AND_MEAN
#include "windowCreation.h"
#include "vertex_buffer.h"
#include "shader.h"

#include <comdef.h>
#include "start_console.h"
//hInstance: Used to identify the .exe when it's loaded into memory.
//hPreviousInstance: Always 0.
//pCmdLine: Command-line arguments, convert to argv with CommandLineToArgvW().
//nCmdShow: Flag that says if it should be minimized, maximized or showed normally.
int WINAPI wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance,
    _In_ LPWSTR lpCmdLine, _In_ int nCmdShow) {
        RedirectIOToConsole();
        HWND D3D_window = InitWindow(hInstance);

        if (D3D_window == NULL) {
            return 0;
        }
        assert(D3D_window);

        D3D_create(D3D_window);
        Create_Vertex_Buffer();
        shader_compile_and_layout();

        MSG msg = { };
        ShowWindow(D3D_window, nCmdShow);
        while (msg.message != WM_QUIT) {
            if (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE)) {
                TranslateMessage(&msg);
                DispatchMessage(&msg);
            }
            else {
                FLOAT background_color[4] = { 1, 1, 1, 0 };
                devcon->ClearRenderTargetView(pView, background_color);

                devcon->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
                devcon->IASetInputLayout(input_layout);
                devcon->VSSetShader(vs, NULL, 0);
                devcon->PSSetShader(ps, NULL, 0);


                devcon->IASetVertexBuffers(0, 1, &Vertex_Buffer, &vertex_strides, &vertex_offset);
                devcon->Draw(3, 0);
                swapchain->Present(1, 0);
            }
        }
        DestroyWindow(D3D_window);
        CleanD3D();
        return 0;
}

windowCreation.h

#ifndef WINDOWCREATION_H
#define WINDOWCREATION_H
#include <windows.h>    //win32
#include <d3d11.h>      //D3D 11
#include <dxgi.h>       //Graphics devices and swap chain
#include <assert.h>     //for assert()
#include <iostream>
//Libraries
#pragma comment( lib, "user32")             //win32
#pragma comment( lib, "gdi32")              //Graphics device interface
#pragma comment( lib, "d3d11")              //Direct3D 11
#pragma comment( lib, "d3dcompiler.lib")    //Shader Compiler

extern unsigned int width;
extern unsigned int height;

extern IDXGISwapChain *swapchain;
extern ID3D11Device *dev;
extern ID3D11DeviceContext *devcon;

extern ID3D11Texture2D* pSwapChainBuffer;
extern ID3D11RenderTargetView* pView;

//Event handler declaration
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);

HWND InitWindow(HINSTANCE);
void CleanD3D();

void D3D_create_device_and_swapchain(HWND D3D_window);
void D3D_create_rendertarget();
void D3D_create_rasterizer();
void D3D_create_depth_stencil_state();
void D3D_create_blendstate();

void D3D_create(HWND D3D_window);

#endif

windowCreation.cpp

#include "windowCreation.h"

IDXGISwapChain *swapchain;
ID3D11Device *dev;
ID3D11DeviceContext *devcon;

ID3D11Texture2D* pSwapChainBuffer = 0;
ID3D11RenderTargetView* pView = 0;

unsigned int width = 640;
unsigned int height = 480;

ID3D11RasterizerState *pRSState;
ID3D11DepthStencilState* pDepthStencilState;
ID3D11BlendState* pBlendState;

HWND InitWindow(HINSTANCE hInstance) {
    //Declaring the windowclass.
    WNDCLASSEX wc = { 0 };

    wc.cbSize           = sizeof(WNDCLASSEX);
    wc.style            = CS_HREDRAW | CS_VREDRAW;
    wc.lpfnWndProc      = WindowProc;               //Pointer to the windowproc-function that handles events.
    wc.hInstance        = hInstance;                //Handle to the application instance. 
    wc.lpszClassName    = L"BasicWindow";               //Identifies the window class

    //Registers the window class with the opserating system
    if (!RegisterClassEx(&wc)) {    
        return 0;
    }

    RECT rc = { 0, 0, width, height };
    AdjustWindowRect(&rc, WS_OVERLAPPEDWINDOW, FALSE);

    HWND D3D_window = CreateWindow(
        L"BasicWindow",                             
        L"BTH BasicWindow",                         
        WS_OVERLAPPEDWINDOW,            

        //Size and position
        CW_USEDEFAULT, CW_USEDEFAULT, rc.right - rc.left, rc.bottom - rc.top,

        nullptr,                            //Parent window
        nullptr,                            //Menu
        hInstance,                          //Instance handle
        nullptr                             //Additional application data
    );

    return D3D_window;
}

void D3D_create_device_and_swapchain(HWND D3D_window) {
    DXGI_SWAP_CHAIN_DESC scd;

    ZeroMemory(&scd, sizeof(DXGI_SWAP_CHAIN_DESC));

    scd.BufferCount = 1;
    scd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
    scd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
    scd.OutputWindow = D3D_window;
    scd.SampleDesc.Count = 1;
    scd.Windowed = TRUE;

    D3D11CreateDeviceAndSwapChain(
        NULL,
        D3D_DRIVER_TYPE_HARDWARE,
        NULL,
        D3D11_CREATE_DEVICE_DEBUG,
        NULL,
        NULL,
        D3D11_SDK_VERSION,
        &scd,
        &swapchain,
        &dev,
        NULL,
        &devcon
    );
}

void D3D_create_rendertarget() {
    HRESULT hr = swapchain->GetBuffer(  0,
                                        __uuidof(ID3D11Texture2D),
                                        (void**)&pSwapChainBuffer);
    if (FAILED(hr)) {
        std::cout << "fail";
    }
    hr = dev->CreateRenderTargetView(   pSwapChainBuffer,
                                        0,
                                        &pView);
    if (FAILED(hr)) {
        std::cout << "fail";
    }

    devcon->OMSetRenderTargets(1, &pView, nullptr);

    auto viewport = CD3D11_VIEWPORT(0.0f, 0.0f,
        static_cast<float>(width), static_cast<float>(height)
    );

    devcon->RSSetViewports(1, &viewport);
}

void D3D_create_rasterizer() {
    CD3D11_RASTERIZER_DESC desc = {};
    desc.FillMode = D3D11_FILL_SOLID;
    desc.CullMode = D3D11_CULL_NONE;

    HRESULT hr = dev->CreateRasterizerState(&desc, &pRSState);
    if (FAILED(hr)) {
        std::cout << "fail";
    }
    devcon->RSGetState(&pRSState);
}

void D3D_create_depth_stencil_state() {
    D3D11_DEPTH_STENCIL_DESC desc;
    desc.DepthEnable = TRUE;
    desc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
    desc.DepthFunc = D3D11_COMPARISON_LESS;
    desc.StencilEnable = FALSE;
    desc.StencilReadMask = D3D11_DEFAULT_STENCIL_READ_MASK;
    desc.StencilWriteMask = D3D11_DEFAULT_STENCIL_WRITE_MASK;
    desc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
    desc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP;
    desc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
    desc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
    desc.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
    desc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP;
    desc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
    desc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS;

    HRESULT hr = dev->CreateDepthStencilState(&desc, &pDepthStencilState);
    devcon->OMSetDepthStencilState(pDepthStencilState, 1);
}

void D3D_create_blendstate() {
    D3D11_RENDER_TARGET_BLEND_DESC render_desc;
    render_desc.BlendEnable = TRUE;
    render_desc.SrcBlend = D3D11_BLEND_ONE;
    render_desc.DestBlend = D3D11_BLEND_ZERO;
    render_desc.BlendOp = D3D11_BLEND_OP_ADD;
    render_desc.SrcBlendAlpha = D3D11_BLEND_ONE;
    render_desc.DestBlendAlpha = D3D11_BLEND_ZERO;
    render_desc.BlendOpAlpha = D3D11_BLEND_OP_ADD;
    render_desc.RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;

    D3D11_BLEND_DESC desc;
    desc.AlphaToCoverageEnable = FALSE;
    desc.IndependentBlendEnable = FALSE;
    desc.RenderTarget[0] = render_desc;

    HRESULT hr = dev->CreateBlendState(&desc, &pBlendState);
    if (FAILED(hr)) {
        std::cout << "fail";
    }
    devcon->OMSetBlendState(pBlendState, NULL, NULL);
}

void D3D_create(HWND D3D_window) {
    D3D_create_device_and_swapchain(D3D_window);
    D3D_create_rendertarget();
    D3D_create_rasterizer();
    D3D_create_depth_stencil_state();
    D3D_create_blendstate();
}

void CleanD3D() {
    swapchain->Release();
    dev->Release();
    devcon->Release();
}

vertex_buffer.h

#pragma once
#ifndef VERTEX_BUFFER_H
#define VERTEX_BUFFER_H

#include <vector>

extern struct ID3D11Buffer* Vertex_Buffer;
extern unsigned int vertex_strides;
extern unsigned int vertex_offset;

void Create_Vertex_Buffer();

#endif

vertex_buffer.cpp

#include "vertex_buffer.h"
#include "windowCreation.h"
#include "directxmath.h"
using namespace DirectX;

struct VERTEX { 
XMFLOAT3 pos;
XMFLOAT3 col;
};

ID3D11Buffer* Vertex_Buffer;
unsigned int vertex_strides = sizeof(VERTEX);
unsigned int vertex_offset = 0;

void Create_Vertex_Buffer() {
    VERTEX vertex_array[] = {
        {XMFLOAT3(10, 10, 100), XMFLOAT3(0.0f, 0.0f, 0.0f)},
        {XMFLOAT3(100, 10, 100), XMFLOAT3(0.0f, 0.0f, 0.0f)},
        {XMFLOAT3(55, 100, 100), XMFLOAT3(0.0f, 0.0f, 0.0f)}
    };

    D3D11_BUFFER_DESC buffer_struct;
    buffer_struct.ByteWidth = sizeof(VERTEX) * 3;
    buffer_struct.Usage = D3D11_USAGE_DEFAULT;
    buffer_struct.BindFlags = D3D11_BIND_VERTEX_BUFFER;
    buffer_struct.CPUAccessFlags = 0;
    buffer_struct.MiscFlags = 0;
    buffer_struct.StructureByteStride = sizeof(float);

    D3D11_SUBRESOURCE_DATA resource_struct;
    resource_struct.pSysMem = vertex_array;
    resource_struct.SysMemPitch = 0;
    resource_struct.SysMemSlicePitch = 0;

    HRESULT hr = dev->CreateBuffer(&buffer_struct, &resource_struct, &Vertex_Buffer);
    if (FAILED(hr)) {
        std::cout << "fail";
    }
}

vertex_pixel_shader.hlsl

struct VS_INPUT
{
    float3 vColour        : COLOR;
    float3 vPosition    : POSITION;
};

struct VS_OUTPUT
{
    float3 vColour        : COLOR;
    float4 vPosition    : SV_POSITION;
};

VS_OUTPUT VSMain(VS_INPUT input)
{
    VS_OUTPUT output;

    output.vPosition = float4(input.vPosition.xy, 0.0, 1.0);
    output.vColour = input.vColour;

    return output;
}

float4 PSMain(VS_OUTPUT input) : SV_TARGET
{
    return float4(input.vColour, 1.0);
}

shader.h

#pragma once
#ifndef SHADER_H
#define SHADER_H
#include <d3dcompiler.h>
#include <string>


extern struct ID3D11VertexShader* vs;
extern struct ID3D11PixelShader* ps;

extern struct ID3D11InputLayout* input_layout;

void shader_compile_and_layout();
#endif

shader.cpp

#include "shader.h"
#include "windowCreation.h"
ID3DBlob* blob_vs = nullptr;
ID3DBlob* blob_error_vs = nullptr;
ID3DBlob* blob_ps = nullptr;
ID3DBlob* blob_error_ps = nullptr;

ID3D11VertexShader* vs;
ID3D11PixelShader* ps;
ID3D11InputLayout* input_layout;

void shader_compile_and_layout() {
    HRESULT hr = D3DCompileFromFile(
        L"vertex_pixel_shader.hlsl",
        NULL,
        NULL,
        "VSMain",
        "vs_5_0",
        0,
        0,
        &blob_vs,
        &blob_error_vs);
    if (FAILED(hr)) {
        std::cout << "fail";
    }
    hr = D3DCompileFromFile(
        L"vertex_pixel_shader.hlsl",
        NULL,
        NULL,
        "PSMain",
        "ps_5_0",
        0,
        0,
        &blob_ps,
        &blob_error_ps);
    if (FAILED(hr)) {
        std::cout << "fail";
    }
    dev->CreateVertexShader(blob_vs->GetBufferPointer(), blob_vs->GetBufferSize(), NULL, &vs);
    dev->CreatePixelShader(blob_ps->GetBufferPointer(), blob_ps->GetBufferSize(), NULL, &ps);

    D3D11_INPUT_ELEMENT_DESC input_element_desc[] = {
        {"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0},
        {"COLOR", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0}
    };

    hr = dev->CreateInputLayout(
        input_element_desc, ARRAYSIZE(input_element_desc),
        blob_vs->GetBufferPointer(),
        blob_vs->GetBufferSize(),
        &input_layout
    );
    if (FAILED(hr)) {
        std::cout << "fail";
    }
}

start_console.h

#pragma once
#ifndef VERTEX_BUFFER_H
#define VERTEX_BUFFER_H

#include <vector>

extern struct ID3D11Buffer* Vertex_Buffer;
extern unsigned int vertex_strides;
extern unsigned int vertex_offset;

void Create_Vertex_Buffer();

#endif

start_console.cpp

#include "start_console.h"
#include "windowCreation.h"

void RedirectIOToConsole()
{
    AllocConsole();
    HANDLE stdHandle;
    int hConsole;
    FILE* fp;
    stdHandle = GetStdHandle(STD_OUTPUT_HANDLE);
    hConsole = _open_osfhandle((long)stdHandle, _O_TEXT);
    fp = _fdopen(hConsole, "w");

    freopen_s(&fp, "CONOUT$", "w", stdout);
}
c++ directx-11 direct3d rasterizing
1个回答
0
投票

对于Direct3D,设置所有相关状态至关重要。

  • 我看不到您调用OMSetRenderTargets通过您的渲染目标视图将交换链绑定到渲染上下文
devcon->OMSetRenderTarget(1, &pView, nullptr);
  • 我没有看到对RSSetViewports的调用以设置正确的渲染像素矩形。
auto viewport = CD3D11_VIEWPORT(0.0f, 0.0f,
        static_cast<float>(backBufferWidth),
        static_cast<float>(backBufferHeight)
        );

devcon->RSSetViewports(1, &viewport);
  • 您似乎没有通过控制消隐模式的RSSetState设置渲染状态对象。如果您未将其默认设置,则将剔除模式设置为“后向剔除”,并且FrontCounterClockwise为FALSE。您的顶点数据可能使用了错误的缠绕,最终导致背面被剔除。一个好的开始是用“ Cull None”创建一个对象。
ID3D11RasterizerState *pRSState;

auto desc = CD3D11_RASTERIZER_DESC
D3D11_RASTERIZER_DESC desc = {};
desc.FillMode = D3D11_FILL_SOLID;
desc.CullMode = D3D11_CULL_NONE;
hr = dev->CreateRasterizerState(&desc, &pRSState);

devcon->RSSetState(pRSState);
  • 另一个重要状态是通过OMSetBlendState的混合状态。默认为不透明设置。

  • 您没有深度缓冲区,但是如果您确定要设置OMSetDepthStencilState

由于您仍在开始使用,您可能应该禁用MSAA,直到其他所有功能都可以使用。

scd.SampleDesc.Count = 1;

我可能要参考GitHub上的完整基本渲染循环和设备模板。

您也应该看一下DirectX Tool Kit

© www.soinside.com 2019 - 2024. All rights reserved.