Directx11 渲染与C++不起作用

Directx11 Rendering with C++ Not Working

本文关键字:C++ 不起作用 Directx11      更新时间:2023-10-16

我开始练习使用 directx11 渲染。我已经在directx 9中完成了渲染。但是DX11是一个痛苦的屁股。我甚至无法画一个简单的火车。我不知道我做错了什么。

我尝试删除深度和模板缓冲区,但徒劳无功。因此,在对此问题沉思了2个小时之后,我仍然找不到解决方案。

任何人都可以好心地帮助我..请伙计们

谢谢

这是完整的代码

#include <Windows.h>
#include <windowsx.h>
#include <D3D11.h>
#include <D3DX10math.h>
#include <dxerr.h>
#include <D3DX11.h>
#include <D3DX10.h>
#include "CoreApp.h"
#include "AppTime.h"

using namespace std;
#pragma comment (lib, "d3d11.lib")
#pragma comment (lib, "d3dx11.lib")
#pragma comment (lib, "d3dx10.lib")


LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
bool InitWindowClass(HINSTANCE hinst,int shw,HWND * _hwnd,WNDCLASSEX * exClass);
RECT windowWidth = {0,0, 512,512};
void TW_CALL _Callbak(void * clenddata);
void InitPipeline();
void initGraphics();


ID3D11VertexShader * vshader = 0;
ID3D11PixelShader * pixelShader = 0;
ID3D11Device * d3dDevice = 0;   
ID3D11DeviceContext * d3dContext = 0;
#pragma region verticles
struct CVertex
{
    float X,Y,Z;
    D3DXCOLOR col;
};
namespace Color
{
    D3DXCOLOR white (255);
    D3DXCOLOR Red ((float)255,0.0,0.0,1.0);
}
#pragma endregion

int WINAPI WinMain(HINSTANCE inst,HINSTANCE previnst,LPSTR cmdLine,int show)
{

    // Window Params
    HWND hwnd;
    WNDCLASSEX exClass;
    MSG msg;
    GameTime time;
    // Iniitaliztion
    SecureZeroMemory(&hwnd,sizeof(HWND));
    SecureZeroMemory(&exClass,sizeof(exClass));
    SecureZeroMemory(&msg,sizeof(MSG));
    SecureZeroMemory(&time,sizeof(time));
if(InitWindowClass(inst,show,&hwnd,&exClass))
    {
    // Directx  11 Functionalities
        #pragma region Create the device

        D3D_FEATURE_LEVEL feature_LEVEL; // Output feature level

            HRESULT hr = D3D11CreateDevice(0,
                                           D3D_DRIVER_TYPE_HARDWARE,
                                           0,
                                           0,       // No flags 
                                           0,0,
                                           D3D11_SDK_VERSION,
                                           &d3dDevice,
                                           &feature_LEVEL,&d3dContext);
            if(FAILED(hr))
            {
                MessageBox(hwnd,L"Failed TO CREATE DEVICE",L"ERROR",0);
            }
      #pragma endregion
        #pragma region Multisampling
            UINT multisampleQuality = 0;
            d3dDevice->CheckMultisampleQualityLevels(DXGI_FORMAT_B8G8R8A8_UNORM,4,&multisampleQuality);

        #pragma endregion
        #pragma region DescribeSwapChain
            DXGI_SWAP_CHAIN_DESC swapDesc;
            // Allocate Mommory
             SecureZeroMemory(&swapDesc,sizeof(DXGI_SWAP_CHAIN_DESC));
            swapDesc.BufferDesc.Width =  512;
            swapDesc.BufferDesc.Height = 512;
            swapDesc.BufferDesc.RefreshRate.Numerator= 60;
            swapDesc.BufferDesc.RefreshRate.Denominator = 1;
            swapDesc.BufferDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
            swapDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
            swapDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
            //MSAA 
            swapDesc.SampleDesc.Count = 4;
            swapDesc.SampleDesc.Quality = multisampleQuality -1;
            //BackBuffer
            swapDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
            swapDesc.BufferCount = 1;
            swapDesc.OutputWindow = hwnd;
            swapDesc.Windowed = true;
            swapDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
            swapDesc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;

        #pragma endregion
        #pragma region CreateSwapChain
            #pragma region Obtain DXGIFactory
        // DXGIFactory >> DXGIAdaptor >> DXGIDevice
            // Get the DXGI device
            IDXGIDevice * dxgiDevice = 0;
            d3dDevice->QueryInterface(__uuidof(IDXGIDevice),(void**)&dxgiDevice);
            // Obtain DXGIAdaptor
            IDXGIAdapter * dxgiAdaptor = 0;
            dxgiDevice->GetParent(__uuidof(IDXGIAdapter),(void**)&dxgiAdaptor);
            IDXGIFactory * dxgiFactory = 0;
            dxgiAdaptor->GetParent(__uuidof(IDXGIFactory),(void**)&dxgiFactory);
            #pragma endregion

            IDXGISwapChain * SwapChain = 0;
                if(FAILED(dxgiFactory->CreateSwapChain(d3dDevice,&swapDesc,&SwapChain)))
                {
                    MessageBox(hwnd,L"Failed Creating back buffer",L"Error",0);
                }

                dxgiFactory->MakeWindowAssociation(hwnd,0);

                //Release COMs
            dxgiAdaptor->Release();
            dxgiDevice->Release();
            dxgiFactory->Release();
            /*IDXGISwapChain * SwapChain = 0;
            if(FAILED(D3D11CreateDeviceAndSwapChain(0,D3D_DRIVER_TYPE_HARDWARE,0,0,0,0,D3D11_SDK_VERSION,&swapDesc,&SwapChain,&d3dDevice,&feature_LEVEL,&d3dContext)))
            {
                MessageBox(hwnd,L"Failed Creating back buffer and device",L"Error",0);
            }*/

        #pragma endregion
        #pragma region Create Render Target View
            ID3D11RenderTargetView * RenderTarget ;
            ID3D11Texture2D * backBuffer ;
            SecureZeroMemory(&backBuffer,sizeof(ID3D11Texture2D));
            SecureZeroMemory(&RenderTarget,sizeof(ID3D11RenderTargetView));
            SwapChain->GetBuffer(0,__uuidof(ID3D11Texture2D),(void**)&backBuffer);
            d3dDevice->CreateRenderTargetView(backBuffer,NULL,&RenderTarget);
        //  d3dContext->OM
            //Release COM
            backBuffer->Release();

        #pragma endregion
        #pragma region Create Depth Stencil Texture
            D3D11_TEXTURE2D_DESC depthDesc;
            SecureZeroMemory(&depthDesc,sizeof(depthDesc)); // Allocate Memeory
            depthDesc.ArraySize = 1;
            //Flags
            depthDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
            depthDesc.CPUAccessFlags = 0;
            depthDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; // Format
            // Area
            depthDesc.Height = 512;
            depthDesc.Width = 512;
            // Mipmap and MXAA
            depthDesc.MipLevels= 1;
            depthDesc.SampleDesc.Count = 4;
            depthDesc.SampleDesc.Quality = multisampleQuality -1;

            depthDesc.Usage = D3D11_USAGE_DEFAULT;
            depthDesc.MiscFlags = 0;
            // Create and initialize pointers
            ID3D11Texture2D * DepthTexture = 0;
            ID3D11DepthStencilView * depthView = 0;
            //d3dDevice->CreateTexture2D(&depthDesc,0,&DepthTexture);
        //  d3dDevice->CreateDepthStencilView(DepthTexture,0,&depthView);

        #pragma endregion
        #pragma region Bind to Output
            d3dContext->OMSetRenderTargets(1,&RenderTarget,NULL); // removed depth buffer for testing but still wont work
        #pragma endregion
        #pragma region Create ViewPort
            D3D11_VIEWPORT viewport;
            //Clear mommory
            SecureZeroMemory(&viewport,sizeof(viewport));
            viewport.Height = 512;
            viewport.Width = 512;
            viewport.MinDepth = 0;
            viewport.MaxDepth = 1;
            viewport.TopLeftX = 0;
            viewport.TopLeftY = 0;
            d3dContext->RSSetViewports(1,&viewport);
        #pragma endregion

            TwInit(ETwGraphAPI::TW_DIRECT3D11,d3dDevice);
            TwWindowSize(swapDesc.BufferDesc.Width,swapDesc.BufferDesc.Height);

            time.Reset();
            InitPipeline();
            #pragma region Vertex Buffer Creation
            CVertex vertex[3] = {
                {0,0,0,Color::white},
                {0.5,0,0,Color::white},
                {0.25,0.5,0,Color::Red},
            };
            D3D11_BUFFER_DESC VbufferDesc;
            D3D11_SUBRESOURCE_DATA vBufferInit;
            SecureZeroMemory(&vertex,sizeof(vertex));
                SecureZeroMemory(&VbufferDesc,sizeof(VbufferDesc));
                SecureZeroMemory(&vBufferInit,sizeof(vBufferInit));
                VbufferDesc.Usage = D3D11_USAGE_DEFAULT;
                VbufferDesc.BindFlags = D3D10_BIND_VERTEX_BUFFER;
                VbufferDesc.ByteWidth = 3* sizeof(CVertex);
                VbufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_FLAG::D3D11_CPU_ACCESS_READ;
                VbufferDesc.MiscFlags = 0;
                VbufferDesc.StructureByteStride = 0;

                vBufferInit.pSysMem = vertex;
                ID3D11Buffer * Vbuffer = {0};
                    d3dDevice->CreateBuffer(&VbufferDesc,&vBufferInit,&Vbuffer);

            #pragma endregion
            while(msg.message != WM_QUIT)
        {
            if(PeekMessage(&msg,hwnd,0,0,PM_REMOVE))
          {
              TranslateMessage(&msg);
              DispatchMessage(&msg);
            }else{

             // Update Sequences
                // Rendering
                d3dContext->ClearRenderTargetView(RenderTarget,D3DXCOLOR(0,0,300,0));

                UINT stride = sizeof(CVertex);
                UINT offset = 0;    
                d3dContext->IASetVertexBuffers(0,1,&Vbuffer,&stride,&offset);
                d3dContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY::D3D10_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
                d3dContext->Draw(3,0);

                SwapChain->Present(0,0);
            }
        }
    }
    return msg.wParam;
}
void InitPipeline()
{
    ID3D10Blob * vBuffBlob = 0;
ID3D10Blob * pBuffBlob = 0;
    //SecureZeroMemory(&vBuffBlob,sizeof(ID3D10Blob));
    //SecureZeroMemory(&pBuffBlob,sizeof(ID3D10Blob));
    SecureZeroMemory(&vshader,sizeof(ID3D11VertexShader));
    SecureZeroMemory(&pixelShader,sizeof(ID3D11PixelShader));
    HRESULT hr = D3DX11CompileFromFile(L"source.shader",0,0,"VShader","vs_4_0",0,0,0,&vBuffBlob,0,0);
    D3DX11CompileFromFile(L"source.shader",0,0,"PShader","ps_4_0",0,0,0,&pBuffBlob,0,0);
    if(FAILED(hr))
        MessageBeep(1);
    d3dDevice->CreateVertexShader(vBuffBlob->GetBufferPointer(),vBuffBlob->GetBufferSize(),NULL,&vshader);
    d3dDevice->CreatePixelShader(pBuffBlob->GetBufferPointer(),pBuffBlob->GetBufferSize(),NULL,&pixelShader);

D3D11_INPUT_ELEMENT_DESC inp[] = {
    {"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}
};
    SecureZeroMemory(inp,sizeof(inp));
    ID3D11InputLayout * inputL = 0;
    d3dDevice->CreateInputLayout(inp,2,vBuffBlob->GetBufferPointer(),vBuffBlob->GetBufferSize(),&inputL);

    d3dContext->IASetInputLayout(inputL);
                d3dContext->VSSetShader(vshader,NULL,0);
                d3dContext->PSSetShader(pixelShader,0,0);
    pBuffBlob->Release();
    vBuffBlob->Release();
}

// Initialize and show the Window
bool InitWindowClass(HINSTANCE hinst,int shw,HWND * _hwnd,WNDCLASSEX * exClass)
{
     exClass->cbSize = sizeof(WNDCLASSEX);
     exClass->hCursor = LoadCursor(0,IDC_ARROW);
     exClass->hInstance = hinst;
     exClass->lpfnWndProc = WndProc;
     exClass->lpszClassName = L"DX_Test";
     exClass->lpszMenuName = L"Test";
     exClass->hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
     RegisterClassEx(exClass);

     AdjustWindowRect(&windowWidth,WS_OVERLAPPEDWINDOW,false);
     (*_hwnd) = CreateWindowEx(0,L"DX_Test",L"Test",WS_OVERLAPPEDWINDOW,500,200,windowWidth.right -  windowWidth.left,windowWidth.bottom-windowWidth.top,NULL,NULL,hinst,0);
     ShowWindow((*_hwnd),shw);

     UpdateWindow(*_hwnd);
     return true;
}

// Message Loop
LRESULT CALLBACK WndProc(HWND hwnd,UINT msg,WPARAM wparam,LPARAM lparam)
{
   .....

首先,您没有正确初始化D3D11_INPUT_ELEMENT_DESC结构。你有:

D3D11_INPUT_ELEMENT_DESC inp[] = {
    {"POSITION",0,DXGI_FORMAT_R32G32B32A32_FLOAT,0,0},
    {"COLOR",0,DXGI_FORMAT_R32G32B32A32_FLOAT,0,12}
};
SecureZeroMemory(inp,sizeof(inp));

它部分初始化结构,然后将其完全归零。该代码片段应为:

D3D11_INPUT_ELEMENT_DESC inp[] = {
    {"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},
};

它给出了输入的完整描述以及它在内存中的布局方式。

其次,我建议把整个项目放在一边,花大约一周的时间阅读Chuck链接的两个教程,尽可能多地阅读MSDN的信息,并仔细阅读Frank D. Luna的书。很多这些东西在他的书中都有涉及,所有的代码都可以在网上找到,所以这本书不需要学习API(尽管它肯定有帮助(。

DirectX 9 更容易习惯,因为固定函数管道有助于组织大量额外的工作。但是,如果使用 DirectX 9.0c 和着色器模型 2.x/3,则此代码中的许多代码非常相似,现在需要这些代码,因为 D3D 中不再有固定的函数管道。