C++ Direct3D:尝试绘制三角形,但未显示任何内容
我正在学习Direct3D11,我试图显示一个三角形,我遵循了所有必要的步骤,但没有显示任何内容。 这是我的密码:C++ Direct3D:尝试绘制三角形,但未显示任何内容,c++,directx,directx-11,C++,Directx,Directx 11,我正在学习Direct3D11,我试图显示一个三角形,我遵循了所有必要的步骤,但没有显示任何内容。 这是我的密码: #include <Windows.h> #include <dxgi1_4.h> #include <d3d11.h> #include <d3dcompiler.h> #include "Game.h" Game *Game::game = nullptr; Game *Game::GetInstance() { if
#include <Windows.h>
#include <dxgi1_4.h>
#include <d3d11.h>
#include <d3dcompiler.h>
#include "Game.h"
Game *Game::game = nullptr;
Game *Game::GetInstance()
{
if (Game::game == nullptr)
Game::game = new Game();
return game;
}
Game::Game()
{
}
Game::~Game()
{
}
bool Game::Initialize(HINSTANCE hInstance)
{
if (InitializeWindow(hInstance))
return InitializeDirect3D();
return false;
}
bool Game::InitializeWindow(HINSTANCE hInstance)
{
WNDCLASS windowClass = {};
windowClass.hInstance = hInstance;
windowClass.lpfnWndProc = &WndProc;
windowClass.lpszClassName = L"wndClass";
windowClass.lpszMenuName = NULL;
windowClass.style = CS_HREDRAW | CS_VREDRAW;
windowClass.cbClsExtra = 0;
windowClass.cbWndExtra = 0;
windowClass.hCursor = LoadCursor(NULL, IDC_ARROW);
windowClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
windowClass.hbrBackground = (HBRUSH)GetStockObject(GRAY_BRUSH);
RegisterClass(&windowClass);
mWindow = CreateWindow(L"wndClass", L"DirectX 12 Engine", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 0, 0, hInstance, 0);
if (!mWindow)
{
MessageBox(0, L"window creation failed", L"ERROR", MB_OK);
return false;
}
ShowWindow(mWindow, SW_SHOW);
UpdateWindow(mWindow);
return true;
}
bool Game::InitializeDirect3D()
{
HRESULT hr;
// create the device and the device context
const D3D_FEATURE_LEVEL featureLevels[] = { D3D_FEATURE_LEVEL_11_0 };
D3D_FEATURE_LEVEL featureLevel;
hr = D3D11CreateDevice(nullptr, D3D_DRIVER_TYPE_HARDWARE, 0, D3D11_CREATE_DEVICE_DEBUG, featureLevels, 1, D3D11_SDK_VERSION, &mDevice, &featureLevel, &mDeviceContext);
if (FAILED(hr))
{
MessageBox(mWindow, L"device creation failed", L"ERROR", MB_OK);
return false;
}
if (featureLevel != D3D_FEATURE_LEVEL_11_0)
{
MessageBox(mWindow, L"DirectX 11 not supported", L"ERROR", MB_OK);
return false;
}
// query 4X MSAA support
mDevice->CheckMultisampleQualityLevels(DXGI_FORMAT_R8G8B8A8_UNORM, 4, &m4xMsaaQuality);
if (m4xMsaaQuality <= 0)
{
MessageBox(mWindow, L"4X MSAA not supported", L"ERROR", MB_OK);
return false;
}
// describe and create the swap chain
DXGI_MODE_DESC modeDesc = {};
modeDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
modeDesc.Width = mClientWidth;
modeDesc.Height = mClientHeight;
modeDesc.RefreshRate.Denominator = 1;
modeDesc.RefreshRate.Numerator = 60;
modeDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
modeDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
DXGI_SWAP_CHAIN_DESC swapChainDesc = {};
swapChainDesc.BufferDesc = modeDesc;
swapChainDesc.BufferCount = 1;
swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
swapChainDesc.Flags = 0;
swapChainDesc.OutputWindow = mWindow;
swapChainDesc.Windowed = true;
swapChainDesc.SampleDesc.Count = 4;
swapChainDesc.SampleDesc.Quality = m4xMsaaQuality - 1;
swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
IDXGIDevice *device = nullptr;
mDevice->QueryInterface(IID_PPV_ARGS(&device));
IDXGIAdapter *adapter = nullptr;
device->GetParent(IID_PPV_ARGS(&adapter));
IDXGIFactory *factory = nullptr;
adapter->GetParent(IID_PPV_ARGS(&factory));
hr = factory->CreateSwapChain(mDevice, &swapChainDesc, &mSwapChain);
if (FAILED(hr))
{
MessageBox(mWindow, L"swap chain creation failed", L"ERROR", MB_OK);
return false;
}
device->Release();
adapter->Release();
factory->Release();
// create the render target view
ID3D11Texture2D *texture = nullptr;
mSwapChain->GetBuffer(0, IID_PPV_ARGS(&texture));
mDevice->CreateRenderTargetView(texture, nullptr, &mRenderTargetView);
texture->Release();
// bind render target views to output merger stage of graphics pipeline
mDeviceContext->OMSetRenderTargets(1, &mRenderTargetView, nullptr);
// set the viewport
D3D11_VIEWPORT viewport;
viewport.TopLeftX = 0.0f;
viewport.TopLeftY = 0.0f;
viewport.Width = static_cast<float>(mClientWidth);
viewport.Height = static_cast<float>(mClientHeight);
viewport.MinDepth = 0.0f;
viewport.MaxDepth = 1.0f;
mDeviceContext->RSSetViewports(1, &viewport);
CreateShaders();
CreateBuffers();
CreateInputLayout();
return true;
}
bool Game::CreateShaders()
{
HRESULT hr;
// compile shaders
ID3DBlob *error;
hr = D3DCompileFromFile(L"shaders/VertexShader.hlsl", nullptr, nullptr, "main", "vs_5_0", 0, 0, &mVertexShaderBlob, &error);
if (FAILED(hr))
{
ErrorBox(L"vertex shader compilation failed");
OutputDebugStringA((LPCSTR)error->GetBufferPointer());
return false;
}
hr = D3DCompileFromFile(L"shaders/PixelShader.hlsl", nullptr, nullptr, "main", "ps_5_0", 0, 0, &mPixelShaderBlob, &error);
if (FAILED(hr))
{
ErrorBox(L"pixel shader compilation failed");
OutputDebugStringA((LPCSTR)error->GetBufferPointer());
return false;
}
// create shaders
hr = mDevice->CreateVertexShader(mVertexShaderBlob->GetBufferPointer(), mVertexShaderBlob->GetBufferSize(), nullptr, &mVertexShader);
if (FAILED(hr))
{
ErrorBox(L"vertex shader creation failed");
return false;
}
hr = mDevice->CreatePixelShader(mPixelShaderBlob->GetBufferPointer(), mPixelShaderBlob->GetBufferSize(), nullptr, &mPixelShader);
if (FAILED(hr))
{
ErrorBox(L"pixel shader creation failed");
return false;
}
return true;
}
bool Game::CreateBuffers()
{
HRESULT hr;
// define geometry
struct Vertex
{
float position[3];
};
Vertex vertices[] = {
{-0.5f, -0.5f, 0.0f},
{-0.5f, 0.5f, 0.0f},
{0.5f, 0.0f, 0.0f}
};
// create vertex buffer
D3D11_BUFFER_DESC bufferDesc = {};
bufferDesc.Usage = D3D11_USAGE_DYNAMIC;
bufferDesc.ByteWidth = sizeof vertices;
bufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
bufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
bufferDesc.MiscFlags = 0;
bufferDesc.StructureByteStride = 0;
D3D11_SUBRESOURCE_DATA data = {};
data.pSysMem = vertices;
hr = mDevice->CreateBuffer(&bufferDesc, &data, &mVertexBuffer);
if (FAILED(hr))
{
ErrorBox(L"vertex buffer creation failed");
return false;
}
return true;
}
bool Game::CreateInputLayout()
{
HRESULT hr;
// describe input layout
D3D11_INPUT_ELEMENT_DESC inputLayout[] = {
{"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0},
};
// create input layout
hr = mDevice->CreateInputLayout(inputLayout, 1, mVertexShaderBlob->GetBufferPointer(), mVertexShaderBlob->GetBufferSize(), &mInputLayout);
if (FAILED(hr))
{
ErrorBox(L"input layout creation failed");
return false;
}
return true;
}
int Game::Run()
{
MSG msg;
do
{
if (PeekMessage(&msg, 0, 0, 0, PM_REMOVE) != 0)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
Draw();
} while (msg.message != WM_QUIT);
return (int)msg.wParam;
}
// custom vertex format
struct Vertex
{
float position[3];
unsigned char color[4];
};
void Game::Draw()
{
const float color[] = { 0.0f, 1.0f, 0.0f, 1.0f };
mDeviceContext->ClearRenderTargetView(mRenderTargetView, color);
// set shaders
mDeviceContext->VSSetShader(mVertexShader, nullptr, 0);
mDeviceContext->PSSetShader(mPixelShader, nullptr, 0);
// set vertex buffer
UINT stride = sizeof(Vertex);
UINT offset = 0;
mDeviceContext->IASetVertexBuffers(0, 1, &mVertexBuffer, &stride, &offset);
// set input layout
mDeviceContext->IASetInputLayout(mInputLayout);
// set primitive topology
mDeviceContext->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
// draw
mDeviceContext->Draw(3, 0);
mSwapChain->Present(0, 0);
}
LRESULT CALLBACK Game::GameWndProc(HWND window, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_LBUTTONDOWN:
MessageBox(mWindow, L"left mouse button clicked", L"CLICK", MB_OK);
return 0;
case WM_RBUTTONDOWN:
MessageBox(mWindow, L"right mouse button clicked", L"CLICK", MB_OK);
return 0;
case WM_CLOSE:
if (MessageBox(mWindow, L"are you sure you want to quit?", L"QUIT", MB_YESNO) == IDYES)
PostQuitMessage(0);
return 0;
default:
return DefWindowProc(window, msg, wParam, lParam);
}
}
LRESULT CALLBACK WndProc(HWND window, UINT msg, WPARAM wParam, LPARAM lParam)
{
return Game::GetInstance()->GameWndProc(window, msg, wParam, lParam);
}
void ErrorBox(wchar_t *message)
{
MessageBox(Game::GetInstance()->mWindow, message, L"ERROR", MB_OK);
}
#包括
#包括
#包括
#包括
#包括“Game.h”
Game*Game::Game=nullptr;
Game*Game::GetInstance()
{
如果(游戏::游戏==nullptr)
游戏::游戏=新游戏();
回归游戏;
}
Game::Game()
{
}
游戏::~Game()
{
}
bool游戏::初始化(HINSTANCE HINSTANCE)
{
if(初始化为INDOW(hInstance))
返回initializedDirect3D();
返回false;
}
bool游戏::初始化窗口(HINSTANCE HINSTANCE)
{
WNDCLASS windowClass={};
windowClass.hInstance=hInstance;
windowClass.lpfnWndProc=&WndProc;
windowClass.lpszClassName=L“wndClass”;
windowClass.lpszMenuName=NULL;
windowClass.style=CS_HREDRAW | CS_VREDRAW;
windowClass.cbClsExtra=0;
windowClass.cbWndExtra=0;
windowClass.hCursor=LoadCursor(空,IDC_箭头);
windowClass.hIcon=加载图标(空,IDI_应用程序);
windowClass.hbrBackground=(HBRUSH)GetStockObject(灰色画笔);
RegisterClass(&windowClass);
mWindow=CreateWindow(L“wndClass”,L“DirectX 12引擎”,WS_重叠窗口,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,0,0,hInstance,0);
如果(!mWindow)
{
消息框(0,L“窗口创建失败”,L“错误”,MB_OK);
返回false;
}
展示窗口(mWindow、SW_SHOW);
更新窗口(mWindow);
返回true;
}
布尔游戏::InitializeDirect3D()
{
HRESULT-hr;
//创建设备和设备上下文
常量D3D_特征层特征层[]={D3D_特征层11_0};
D3D_特征级特征级;
hr=D3D11CreateDevice(nullptr、D3D驱动程序、类型硬件、0、D3D11、创建设备、调试、功能级别、1、D3D11、SDK版本、&mDevice、&featureLevel、&mDeviceContext);
如果(失败(小时))
{
MessageBox(mWindows,L“设备创建失败”,L“错误”,MB_OK);
返回false;
}
如果(功能级别!=D3D\U功能级别\U 11\U 0)
{
MessageBox(mWindows,L“不支持DirectX 11”,L“错误”,MB_OK);
返回false;
}
//查询4X MSAA支持
mDevice->CheckMultisampleQualityLevels(DXGI_格式_R8G8B8A8_UNORM、4和m4xMsaaQuality);
if(M4XMSAA质量查询接口(IID_PPV_参数和设备));
IDXGIAdapter*适配器=空PTR;
设备->获取父级(IID_PPV_参数(&adapter));
IDXGIFactory*工厂=空PTR;
适配器->获取父级(IID_PPV_参数(&factory));
hr=工厂->创建SwapChain(mDevice和swapChainDesc和mSwapChain);
如果(失败(小时))
{
MessageBox(mWindows,L“交换链创建失败”,L“错误”,MB_OK);
返回false;
}
设备->释放();
适配器->释放();
工厂->发布();
//创建渲染目标视图
ID3D11Texture2D*纹理=空PTR;
mSwapChain->GetBuffer(0,IID_PPV_参数(&texture));
mDevice->CreateRenderTargetView(纹理、nullptr和mRenderTargetView);
纹理->释放();
//将渲染目标视图绑定到图形管道的输出合并阶段
mDeviceContext->OMSetRenderTargets(1,&mRenderTargetView,nullptr);
//设置视口
D3D11_视口;
viewport.TopLeftX=0.0f;
viewport.TopLeftY=0.0f;
viewport.Width=静态投影(mClientWidth);
viewport.Height=静态投影(mClientHeight);
viewport.MinDepth=0.0f;
viewport.MaxDepth=1.0f;
mDeviceContext->RSSETViewport(1,视口和视口);
CreateShaders();
CreateBuffers();
CreateInputLayout();
返回true;
}
bool游戏::CreateShaders()
{
HRESULT-hr;
//编译着色器
ID3DBlob*错误;
hr=D3DCompileFromFile(L“shaders/VertexShader.hlsl”、nullptr、nullptr、“main”、“vs_5_0”、0、0和mVertexShaderBlob、&error);
如果(失败(小时))
{
ErrorBox(L“顶点着色器编译失败”);
OutputDebugStringA((LPCSTR)错误->GetBufferPointer());
返回false;
}
hr=D3DCompileFromFile(L“shaders/PixelShader.hlsl”、nullptr、nullptr、main、ps_5_0、0、0和mPixelShaderBlob、&error);
如果(失败(小时))
{
ErrorBox(L“像素着色器编译失败”);
OutputDebugStringA((LPCSTR)错误->GetBufferPointer());
返回false;
}
//创建着色器
hr=mDevice->CreateVertexShader(mVertexShaderBlob->GetBufferPointer(),mVertexShaderBlob->GetBufferSize(),nullptr,&mVertexShader);
如果(失败(小时))
{
ErrorBox(L“顶点着色器创建失败”);
返回false;
}
hr=mDevice->CreatePixelShader(mPixelShaderBlob->GetBufferPointer(),mPixelShaderBlob->GetBufferSize(),nullptr,&mPixelShader);
如果(失败(小时))
{
ErrorBox(L“像素着色器创建失败”);
返回false;
}
返回true;
}
bool游戏::CreateBuffers()
{
HRESULT-hr;
//定义几何图形
结构顶点
{
浮动位置[3];
};
顶点[]={
{-0.5f,-0.5f,0.0f},
{-0.5f,0.5f,0.0f},
{0.5f,0.0f,0.0f}
};
//创建顶点缓冲区
D3D11_BUFFER_DESC bufferDesc={};
bufferDesc.Usage=D3D11\u Usage\u DYNAMIC;
bufferDesc.ByteWidth=顶点的大小;
bufferDesc.CPUAccessFlags=D3D11\u CPU\u访问\u写入;
bufferDesc.BindFlags=D3D11_BIND_VERTEX_BUFFER;
bufferDesc.miscsflags=0;
bufferDesc.StructureByteStride=0;
D3D11_子资源_数据数据={};
data.psysem=顶点;
hr=mDevice->CreateBuffer(&bufferDesc,&data,&mVertexBuffer);
如果(失败(小时))
{
ErrorBox(L“顶点缓冲区创建失败”);
返回false;
}
返回true;
}
布尔游戏::CreateInputLayout()
{
HRESULT-hr;
//描述输入布局
D3D11_输入_元素_描述输入布局[]={
{“位置”,0,DXGI_格式_R32G32B32_浮点,0,0,D3D11_输入_逐顶点_数据,0},
};
//创建输入布局
hr=mDevice->CreateInputLayout(inputLayout,1,mVertexShaderBlob->GetBufferPointer(),mVertexShaderBlob
ID3D11RasterizerState* rs = 0;
D3D11_RASTERIZER_DESC r;
r.AntialiasedLineEnable = false;
r.CullMode = D3D11_CULL_BACK;
r.DepthBias = 0;
r.DepthBiasClamp = 0.0f;
r.DepthClipEnable = true;
r.FillMode = D3D11_FILL_MODE::D3D11_FILL_SOLID;
r.FrontCounterClockwise = true;
r.MultisampleEnable = false;
r.ScissorEnable = false;
r.SlopeScaledDepthBias = 0.0f;
/*if (FAILED(*/device->CreateRasterizerState(&r,&rs);
d3dcontext->RSSetState(rs);