#include <windows.h>
#include <d3d11.h>
#include <d3dcompiler.h>
#include <DirectXMath.h>
#pragma comment(lib,"./D3D/d3d11.lib")
#pragma comment(lib, "./D3D/d3dcompiler.lib")
IDXGISwapChain* g_pSwapChain = nullptr;
ID3D11Device* g_pd3dDevice = nullptr;
ID3D11DeviceContext* g_pd3dDeviceContext = nullptr;
HWND MainWindowHandle = 0; //主窗口句柄,相当于窗口的ID
bool InitWindowsApp(HINSTANCE instanceHandle, int show); //初始化窗口函数
int Run(); //消息循环函数
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, //消息处理函数
WPARAM wParam, LPARAM lParam);
using namespace DirectX;
//IDXGISwapChain* g_pSwapChain = nullptr;
//ID3D11Device* g_pd3dDevice = nullptr;
ID3D11InputLayout* g_pInputLayout = nullptr;
ID3D11PixelShader* g_pPixelShader = nullptr;
ID3D11VertexShader* g_pVertexShader = nullptr;
ID3D11DeviceContext* g_pImmediateContext = nullptr;
ID3D11RenderTargetView* g_pRenderTargetView = nullptr;
ID3D11Buffer* g_pVertexBuffer = nullptr;
ID3DBlob* pVSBlob = nullptr;
struct VERTEX {
XMFLOAT3 Position;
XMFLOAT4 Color;
};
HRESULT Shader(HWND hWnd)
{
HRESULT hr = D3DCompileFromFile(L"shader.hlsl", nullptr, nullptr, "VSMain", "vs_5_0", 0, 0, &pVSBlob, nullptr);
if (FAILED(hr)) return hr;
hr = g_pd3dDevice->CreateVertexShader(pVSBlob->GetBufferPointer(), pVSBlob->GetBufferSize(), nullptr, &g_pVertexShader); //创建顶点着色器对象
if (FAILED(hr)) {
pVSBlob->Release();
return hr;
}
// 编译并创建像素着色器
ID3DBlob* pPSBlob = nullptr;
hr = D3DCompileFromFile(L"shader.hlsl", nullptr, nullptr, "PSMain", "ps_5_0", 0, 0, &pPSBlob, nullptr);
if (FAILED(hr)) {
pVSBlob->Release();
return hr;
}
hr = g_pd3dDevice->CreatePixelShader(pPSBlob->GetBufferPointer(), pPSBlob->GetBufferSize(), nullptr, &g_pPixelShader);
pVSBlob->Release();
pPSBlob->Release();
if (FAILED(hr)) return hr;
// 设置顶点和像素着色器
g_pImmediateContext->VSSetShader(g_pVertexShader, nullptr, 0);
g_pImmediateContext->PSSetShader(g_pPixelShader, nullptr, 0);
return S_OK;
}
HRESULT InitDirect3D(HWND hWnd)
{
Shader(hWnd);
D3D11_INPUT_ELEMENT_DESC layout[] =
{
{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, offsetof(VERTEX, Position), D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, offsetof(VERTEX, Color), D3D11_INPUT_PER_VERTEX_DATA, 0 },
};
DXGI_SWAP_CHAIN_DESC scd = { 0 };
scd.BufferCount = 1;
scd.BufferDesc.Width = 800;
scd.BufferDesc.Height = 600;
scd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
scd.BufferDesc.RefreshRate.Numerator = 60;
scd.BufferDesc.RefreshRate.Denominator = 1;
scd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
scd.OutputWindow = hWnd;
scd.SampleDesc.Count = 1;
scd.SampleDesc.Quality = 0;
scd.Windowed = TRUE;
D3D_FEATURE_LEVEL FeatureLevelsRequested = D3D_FEATURE_LEVEL_11_0;
UINT numLevelsRequested = 1;
D3D_FEATURE_LEVEL FeatureLevelsSupported;
HRESULT hr = D3D11CreateDeviceAndSwapChain(nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, 0, //创建交换链
&FeatureLevelsRequested, numLevelsRequested, D3D11_SDK_VERSION, &scd, &g_pSwapChain,
&g_pd3dDevice, &FeatureLevelsSupported, &g_pImmediateContext);
if (FAILED(hr)) return hr;
ID3D11Texture2D* pBackBuffer;
hr = g_pSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&pBackBuffer); //创建后备缓冲区
if (FAILED(hr)) return hr;
hr = g_pd3dDevice->CreateRenderTargetView(pBackBuffer, nullptr, &g_pRenderTargetView); //创建渲染目标视图
pBackBuffer->Release();
if (FAILED(hr)) return hr;
// 获取设备上下文
//g_pd3dDevice->GetImmediateContext(&g_pImmediateContext);
g_pImmediateContext->OMSetRenderTargets(1, &g_pRenderTargetView, nullptr); //设置渲染目标
D3D11_VIEWPORT vp;
vp.Width = 800.0f;
vp.Height = 600.0f;
vp.MinDepth = 0.0f;
vp.MaxDepth = 1.0f;
vp.TopLeftX = 0;
vp.TopLeftY = 0;
g_pImmediateContext->RSSetViewports(1, &vp); //设置视口
return S_OK;
}
HRESULT InitVertexBuffer() {
VERTEX vertices[] = {
{ XMFLOAT3(0.0f, 0.5f, 0.0f), XMFLOAT4(1.0f, 0.0f, 0.0f, 1.0f) },
{ XMFLOAT3(0.5f, -0.5f, 0.0f), XMFLOAT4(0.0f, 1.0f, 0.0f, 1.0f) },
{ XMFLOAT3(-0.5f, -0.5f, 0.0f), XMFLOAT4(0.0f, 0.0f, 1.0f, 1.0f) }
};
D3D11_BUFFER_DESC bd = { 0 };
bd.Usage = D3D11_USAGE_DEFAULT;
bd.ByteWidth = sizeof(vertices);
bd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
bd.CPUAccessFlags = 0;
D3D11_SUBRESOURCE_DATA initData = { 0 };
initData.pSysMem = vertices;
HRESULT hr = g_pd3dDevice->CreateBuffer(&bd, &initData, &g_pVertexBuffer);
if (FAILED(hr)) {
return hr;
}
// 设置顶点缓冲区
UINT stride = sizeof(VERTEX);
UINT offset = 0;
g_pImmediateContext->IASetVertexBuffers(0, 1, &g_pVertexBuffer, &stride, &offset);
// 定义输入布局
D3D11_INPUT_ELEMENT_DESC layout[] =
{
{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, offsetof(VERTEX, Position), D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, offsetof(VERTEX, Color), D3D11_INPUT_PER_VERTEX_DATA, 0 },
};
// 创建输入布局
hr = g_pd3dDevice->CreateInputLayout(layout, ARRAYSIZE(layout), pVSBlob->GetBufferPointer(), pVSBlob->GetBufferSize(), &g_pInputLayout);
if (FAILED(hr)) {
return hr;
}
// 设置输入布局
g_pImmediateContext->IASetInputLayout(g_pInputLayout);
// 设置顶点着色器
g_pImmediateContext->VSSetShader(g_pVertexShader, nullptr, 0);
return S_OK;
}
void Render() {
if (!g_pd3dDevice || !g_pImmediateContext) return;
float clearColor[4] = { 0.0f, 0.2f, 0.4f, 1.0f };
g_pImmediateContext->ClearRenderTargetView(g_pRenderTargetView, clearColor);
UINT stride = sizeof(VERTEX);
UINT offset = 0;
g_pImmediateContext->IASetVertexBuffers(0, 1, &g_pVertexBuffer, &stride, &offset);
g_pImmediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
g_pImmediateContext->PSSetShader(g_pPixelShader, nullptr, 0);
g_pImmediateContext->Draw(3, 0);
g_pSwapChain->Present(0, 0);
}
bool InitWindowsApp(HINSTANCE instanceHandle, int show, HWND* hwnd)//初始化窗口函数实现
{
//windows窗口类型的自定义
WNDCLASS wc;
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = instanceHandle;
wc.hIcon = ::LoadIcon(0, IDI_APPLICATION);
wc.hCursor = ::LoadCursor(0, IDC_ARROW);
wc.hbrBackground = static_cast<HBRUSH>(::GetStockObject(WHITE_BRUSH)); //设置窗口的背景画刷:白色
wc.lpszMenuName = 0;
wc.lpszClassName = L"Hello";
//wca = wc;
//向Windows系统注册窗口
if (!::RegisterClass(&wc))
{
::MessageBox(0, L"RegisterClass - Failed", 0, 0);
return false;
}
//根据自定义的窗口进行创建
MainWindowHandle = CreateWindow(L"Hello", L"Hello", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 0, 0, instanceHandle, 0);
//创建失败则弹出消息窗口提示
if (MainWindowHandle == 0)
{
::MessageBox(0, L"CreateWindow - Failed", 0, 0);
return false;
}
::ShowWindow(MainWindowHandle, show); //显示窗口
::UpdateWindow(MainWindowHandle); //进行窗口的刷新
return true;
}
//消息循环函数定义
int Run()
{
MSG msg;
::ZeroMemory(&msg, sizeof(MSG));
while (::GetMessage(&msg, 0, 0, 0))
{
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}
return msg.wParam;
}
//消息处理函数定义
LRESULT CALLBACK WndProc(HWND windowHandle, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_LBUTTONDOWN:
::MessageBox(0, L"Hello, Word", L"Hello", MB_OK);
return 0;
case WM_KEYDOWN:
if (wParam == VK_ESCAPE)
{
::DestroyWindow(MainWindowHandle);
}
return 0;
case WM_DESTROY:
::PostQuitMessage(0);
return 0;
}
return ::DefWindowProc(windowHandle, msg, wParam, lParam);
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR pCmdLine, int nShowCmd)
{
HWND hwnd = NULL;
//初始化失败则弹出消息窗口提示
if (!InitWindowsApp(hInstance, nShowCmd, &hwnd))
{
::MessageBox(0, L"Init - Failed", L"Error", MB_OK);
return 0;
}
if (SUCCEEDED(InitDirect3D(hwnd)) && SUCCEEDED(InitVertexBuffer()))
{
ShowWindow(hwnd, SW_SHOWDEFAULT);
UpdateWindow(hwnd);
MSG msg;
ZeroMemory(&msg, sizeof(msg));
while (msg.message != WM_QUIT)
{
if (PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
Render();
}
}
}
if (g_pVertexBuffer) g_pVertexBuffer->Release();
if (g_pRenderTargetView) g_pRenderTargetView->Release();
if (g_pImmediateContext) g_pImmediateContext->Release();
if (g_pd3dDevice) g_pd3dDevice->Release();
if (g_pSwapChain) g_pSwapChain->Release();
//UnregisterClass((L"Direct3D11 Triangle"), wc.hInstance);
return Run();
}
shader.hlsli
// 顶点着色器
cbuffer ConstantBuffer : register(b0)
{
matrix WorldViewProjection;
};
struct VS_INPUT
{
float3 Position : POSITION;
float4 Color : COLOR;
};
struct VS_OUTPUT
{
float4 Pos : SV_POSITION;
float4 Color : COLOR;
};
VS_OUTPUT VSMain(VS_INPUT input)
{
VS_OUTPUT output;
output.Pos = mul(float4(input.Position, 1.0f), WorldViewProjection);
output.Color = input.Color;
return output;
}
// 像素着色器
struct PS_INPUT
{
float4 Pos : SV_POSITION;
float4 Color : COLOR;
};
float4 PSMain(PS_INPUT input) : SV_TARGET
{
return input.Color;
}
程序运行只有一个窗口三角形压根看不到