其实就是Chili Framework,我想从头到尾把框架再梳理一遍,可能不按教程顺序,代码也不是最新的。主要记录思路,有的放矢。
一 从最底层说起
1. Bindable&Codex模式
对于渲染一个最基本的立方体来说,一般最最最简单的步骤是这样的(忽略掉WindowsSDK那些东西):
void Init()
{
DXGI_SWAP_CHAIN_DESC sd = {
};
sd.BufferDesc.Width = 0;
sd.BufferDesc.Height = 0;
sd.BufferDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
sd.BufferDesc.RefreshRate.Numerator = 0;
sd.BufferDesc.RefreshRate.Denominator = 0;
sd.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
sd.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
sd.SampleDesc.Count = 1;
sd.SampleDesc.Quality = 0;
sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
sd.BufferCount = 1;
sd.OutputWindow = hWnd;
sd.Windowed = TRUE;
sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
sd.Flags = 0;
UINT swapCreateFlags = 0u;
#ifndef NDEBUG
swapCreateFlags |= D3D11_CREATE_DEVICE_DEBUG;
#endif
D3D11CreateDeviceAndSwapChain(
nullptr,
D3D_DRIVER_TYPE_HARDWARE,
nullptr,
swapCreateFlags,
nullptr,
0,
D3D11_SDK_VERSION,
&sd,
pSwap.ReleaseAndGetAddressOf(),
pDevice.ReleaseAndGetAddressOf(),
nullptr,
pContext.ReleaseAndGetAddressOf()
);
// gain access to texture subresource in swap chain (back buffer)
wrl::ComPtr<ID3D11Resource> pBackBuffer;
pSwap->GetBuffer(0, __uuidof(ID3D11Resource), reinterpret_cast<void**>(pBackBuffer.GetAddressOf()));
pDevice->CreateRenderTargetView(pBackBuffer.Get(), nullptr, pTarget.ReleaseAndGetAddressOf());
// create depth stensil state
D3D11_DEPTH_STENCIL_DESC dsDesc = {
};
dsDesc.DepthEnable = TRUE;
dsDesc.DepthFunc = D3D11_COMPARISON_LESS;
dsDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
wrl::ComPtr<ID3D11DepthStencilState> pDSState;
pDevice->CreateDepthStencilState(&dsDesc, pDSState.GetAddressOf());
//bind depth state
pContext->OMSetDepthStencilState(pDSState.Get(), 1u);
// create depth stensil texture
wrl::ComPtr<ID3D11Texture2D> pDepthStencil;
D3D11_TEXTURE2D_DESC descDepth = {
};
descDepth.Width = 800u;
descDepth.Height = 600u;
descDepth.MipLevels = 1u;
descDepth.ArraySize = 1u;
descDepth.Format = DXGI_FORMAT_D32_FLOAT;
descDepth.SampleDesc.Count = 1u;
descDepth.SampleDesc.Quality = 0u;
descDepth.Usage = D3D11_USAGE_DEFAULT;
descDepth.BindFlags = D3D11_BIND_DEPTH_STENCIL;
pDevice->CreateTexture2D(&descDepth, nullptr, pDepthStencil.GetAddressOf());
// create view of depth stensil texture
CD3D11_DEPTH_STENCIL_VIEW_DESC descDSV = {
};
descDSV.Format = DXGI_FORMAT_D32_FLOAT;
descDSV.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
descDSV.Texture2D.MipSlice = 0u;
pDevice->CreateDepthStencilView(
pDepthStencil.Get(),&descDSV,&pDSV
);
// bind depth stensil view to OM
pContext->OMSetRenderTargets(1u, pTarget.GetAddressOf(), pDSV.Get());
}
void PreBeginFrame()
{
// clear buffer
const float color[] = {
red,green,blue ,1.0f };
pContext->ClearRenderTargetView(pTarget.Get(), color);
pContext->ClearDepthStencilView(pDSV.Get(), D3D11_CLEAR_DEPTH, 1.0f, 0u);
}
void DrawTestCube(float xAngle, float yAngle, float zAngle, float x, float y,float z)
{
namespace wrl = Microsoft::WRL;
HRESULT hr;
// ********* pixel shader *********
wrl::ComPtr<ID3D11PixelShader> pPixelShader;
wrl::ComPtr<ID3DBlob> pBlob;
D3DReadFileToBlob(L"PixelShader.cso", pBlob.GetAddressOf());
pDevice->CreatePixelShader(pBlob->GetBufferPointer(), pBlob->GetBufferSize(), nullptr, pPixelShader.GetAddressOf());
pContext->PSSetShader(pPixelShader.Get(), nullptr, 0u);
// ********* end pixel shader *********
// ********* vertex shader *********
wrl::ComPtr<ID3D11VertexShader> pVertexShader;
//pBlob.Reset();
D3DReadFileToBlob(L"VertexShader.cso", pBlob.GetAddressOf());
pDevice->CreateVertexShader(pBlob->GetBufferPointer(), pBlob->GetBufferSize(), nullptr, pVertexShader.GetAddressOf());
pContext->VSSetShader(pVertexShader.Get(), nullptr, 0u);
// ********* end vertex shader
// ********* vertices *********
struct VertexPos3
{
dx::XMFLOAT3 pos;
};
VertexPos3 vertices[] =
{
{
dx::XMFLOAT3(-1.0f, -1.0f, -1.0f) },
{
dx::XMFLOAT3(-1.0f, 1.0f, -1.0f) },
{
dx::XMFLOAT3(1.0f, 1.0f, -1.0f) },
{
dx::XMFLOAT3(1.0f, -1.0f, -1.0f) },
{
dx::XMFLOAT3(-1.0f, -1.0f, 1.0f) },
{
dx::XMFLOAT3(-1.0f, 1.0f, 1.0f) },
{
dx::XMFLOAT3(1.0f, 1.0f, 1.0f) },
{
dx::XMFLOAT3(1.0f, -1.0f, 1.0f) }
};
// input layout
wrl::ComPtr<ID3D11InputLayout> pInputLayout;
D3D11_INPUT_ELEMENT_DESC ied[] = {
{
"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }
};
pDevice->CreateInputLayout(
ied,
(UINT)std::size(ied),
pBlob->GetBufferPointer(),
pBlob->GetBufferSize(),
pInputLayout.GetAddressOf()
);
pContext->IASetInputLayout(pInputLayout.Get());
// vertex buffer
wrl::ComPtr<ID3D11Buffer> pVertexBuffer;
D3D11_BUFFER_DESC vbd;
vbd.ByteWidth = sizeof(vertices);
vbd.Usage = D3D11_USAGE_DEFAULT;
vbd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
vbd.CPUAccessFlags = 0;
vbd.MiscFlags = 0;
vbd.StructureByteStride = 8u;
D3D11_SUBRESOURCE_DATA vsd = {
};
vsd.pSysMem = vertices;
GFX_THROW_INFO(pDevice->CreateBuffer(&vbd, &vsd, pVertexBuffer.GetAddressOf()));
const UINT stride = sizeof(VertexPos3);
const UINT offset = 0u;
pContext->IASetVertexBuffers(0, 1, pVertexBuffer.GetAddressOf(), &stride, &offset);
// ********* end vertex buffer *********
// ********* indices *********
WORD indices[] = {
// 正面
0, 1, 2,
2, 3, 0,
// 左面
4, 5, 1,
1, 0, 4,
// 顶面
1, 5, 6,
6, 2, 1,
// 背面
7, 6, 5,
5, 4, 7,
// 右面
3, 2, 6,
6, 7, 3,
// 底面
4, 0, 3,
3, 7, 4
};
// indices buffer
wrl::ComPtr<ID3D11Buffer> pIndexBuffer;
D3D11_BUFFER_DESC ibd;
ibd.ByteWidth = sizeof(indices);
ibd.Usage = D3D11_USAGE_IMMUTABLE;
ibd.BindFlags = D3D11_BIND_INDEX_BUFFER;
ibd.CPUAccessFlags = 0;
ibd.MiscFlags = 0;
ibd.StructureByteStride = sizeof(WORD);
D3D11_SUBRESOURCE_DATA isd = {
};
isd.pSysMem = indices;
pDevice->CreateBuffer(&ibd, &isd, pIndexBuffer.GetAddressOf());
pContext->IASetIndexBuffer(pIndexBuffer.Get(), DXGI_FORMAT_R16_UINT, 0);
// ********* end indices *********
// ********* constant buffer *********
// configue constant buffer 1 value for VS
struct ConstantBuffer
{
dx::XMMATRIX Scale;
dx::XMMATRIX Rotation;
dx::XMMATRIX Translation;
dx::XMMATRIX View;
dx::XMMATRIX Projection;
};
ConstantBuffer cb;
cb.Scale = dx::XMMatrixTranspose(
dx::XMMatrixIdentity()
);
cb.Rotation = dx::XMMatrixTranspose(
dx::XMMatrixRotationX(xAngle) * dx::XMMatrixRotationY(yAngle) * dx::XMMatrixRotationZ(zAngle)
);
cb.Translation = dx::XMMatrixTranspose(
dx::XMMatrixTranslation(x, 0, z*4)
);
cb.View = dx::XMMatrixTranspose(dx::XMMatrixLookAtLH(
dx::XMVectorSet(0.0f, 0.0f, -5.0f, 0.0f),
dx::XMVectorSet(0.0f, 0.0f, 0.0f, 0.0f),
dx::XMVectorSet(0.0f, 1.0f, 0.0f, 0.0f)
));
cb.Projection = dx::XMMatrixTranspose(
dx::XMMatrixPerspectiveFovLH(
dx::XM_PIDIV2,
800.0f / 600.0f,
1.0f,
1000.0f)
);
wrl::ComPtr<ID3D11Buffer> pConstantBuffer;
D3D11_BUFFER_DESC cbd = {
};
cbd.ByteWidth = sizeof(ConstantBuffer);
cbd.Usage = D3D11_USAGE_DYNAMIC;
cbd.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
cbd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
cbd.MiscFlags = 0;
D3D11_SUBRESOURCE_DATA csd = {
};
csd.pSysMem = &cb;
GFX_THROW_INFO(pDevice->CreateBuffer(&cbd, &csd, pConstantBuffer.GetAddressOf()));
pContext->VSSetConstantBuffers(0, 1, pConstantBuffer.GetAddressOf());
// configue constant buffer 2 value for PS
struct ConstantBuffer2
{
struct
{
float r, g, b, a;
}face_color[6];
};
const ConstantBuffer2 cb2 =
{
{
{
1.0f,0.0f,1.0f},
{
1.0f,0.0f,0.0f},
{
0.0f,1.0f,0.0f},
{
0.0f,